From 3feda05339677a30590230745619db035781752d Mon Sep 17 00:00:00 2001 From: Mobecls Date: Fri, 8 Jun 2018 17:16:42 +0300 Subject: [PATCH 001/812] 14294 - Fixes 'back' functionality after switching a store view. --- .../Store/view/frontend/templates/switch/languages.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml index 80152dbb9a08f..6d041a9e22c5d 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml @@ -27,7 +27,7 @@ getStores() as $_lang): ?> getId() != $block->getCurrentStoreId()): ?>
  • - + escapeHtml($_lang->getName()) ?>
  • From fa2c3b5f5cb37f04c12e12b8bf1673ac0c13a5bb Mon Sep 17 00:00:00 2001 From: Artem Klimov Date: Sat, 30 Jun 2018 15:14:03 +0300 Subject: [PATCH 002/812] Alphabetize Schema Fields#11 --- lib/internal/Magento/Framework/GraphQl/Config.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/internal/Magento/Framework/GraphQl/Config.php b/lib/internal/Magento/Framework/GraphQl/Config.php index 8d40d7fa6bb49..e6dc128e4dd43 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config.php +++ b/lib/internal/Magento/Framework/GraphQl/Config.php @@ -53,6 +53,11 @@ public function getConfigElement(string $configElementName) : ConfigElementInter sprintf('Config element "%s" is not declared in GraphQL schema', $configElementName) ); } + + if (!empty($data['fields']) && is_array($data['fields'])) { + ksort($data['fields']); + } + return $this->configElementFactory->createFromConfigData($data); } From 6a68bd880131a22bacdbf18b25f274c5c8cc236b Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Wed, 25 Jul 2018 13:08:12 +0200 Subject: [PATCH 003/812] Query complexity limiter introduced --- app/code/Magento/GraphQl/etc/di.xml | 6 +++ .../GraphQl/Query/QueryComplexityLimiter.php | 53 +++++++++++++++++++ .../GraphQl/Query/QueryProcessor.php | 23 ++++---- 3 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 105fa8bf166b2..4aed25ac7bf4a 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -97,4 +97,10 @@ + + + 50 + 150 + + diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php new file mode 100644 index 0000000000000..be768d9f8defd --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -0,0 +1,53 @@ +queryDepth = $queryDepth; + $this->queryComplexity = $queryComplexity; + } + + public function execute(bool $disableIntrospection = false): void + { + DocumentValidator::addRule(new QueryDepth($this->queryDepth)); + DocumentValidator::addRule(new QueryComplexity($this->queryComplexity)); + + if ($disableIntrospection) { + DocumentValidator::addRule(new DisableIntrospection()); + } + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php index 94a0e5a1c1a6e..0a23e4d00e8c7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php @@ -7,9 +7,6 @@ namespace Magento\Framework\GraphQl\Query; -use GraphQL\Validator\DocumentValidator; -use GraphQL\Validator\Rules\DisableIntrospection; -use GraphQL\Validator\Rules\QueryDepth; use Magento\Framework\GraphQl\Exception\ExceptionFormatter; use Magento\Framework\GraphQl\Schema; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; @@ -24,12 +21,21 @@ class QueryProcessor */ private $exceptionFormatter; + /** + * @var QueryComplexityLimiter + */ + protected $queryComplexityLimiter; + /** * @param ExceptionFormatter $exceptionFormatter + * @param QueryComplexityLimiter $queryComplexityChecker */ - public function __construct(ExceptionFormatter $exceptionFormatter) - { + public function __construct( + ExceptionFormatter $exceptionFormatter, + QueryComplexityLimiter $queryComplexityChecker + ) { $this->exceptionFormatter = $exceptionFormatter; + $this->queryComplexityLimiter = $queryComplexityChecker; } /** @@ -49,10 +55,9 @@ public function process( array $variableValues = null, string $operationName = null ) : array { - if (!$this->exceptionFormatter->shouldShowDetail()) { - DocumentValidator::addRule(new QueryDepth(10)); - DocumentValidator::addRule(new DisableIntrospection()); - } + $disableIntrospection = $this->exceptionFormatter->shouldShowDetail(); + $this->queryComplexityLimiter->execute($disableIntrospection); + $rootValue = null; return \GraphQL\GraphQL::executeQuery( $schema, From 660e393a1087060a838dc299ea80606ddb08df50 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Thu, 26 Jul 2018 11:11:01 +0200 Subject: [PATCH 004/812] Added some missing PHPDoc --- .../Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index be768d9f8defd..993390f5cfd22 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -41,6 +41,9 @@ public function __construct( $this->queryComplexity = $queryComplexity; } + /** + * @param bool $disableIntrospection + */ public function execute(bool $disableIntrospection = false): void { DocumentValidator::addRule(new QueryDepth($this->queryDepth)); From 351ae3784d0a148c40c89e581f9b6f0f61675a9a Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Thu, 26 Jul 2018 12:04:33 +0200 Subject: [PATCH 005/812] Added API-functional test for query limiter --- .../Framework/QueryComplexityLimiterTest.php | 332 ++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php new file mode 100644 index 0000000000000..fe278eaef1914 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php @@ -0,0 +1,332 @@ +graphQlQuery($query); + } + + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testQueryDepthIsLimited() + { + $query + = <<graphQlQuery($query); + } +} From 9aedd10c130d3455c352d3a3bddad856a75dd82d Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Thu, 26 Jul 2018 12:06:12 +0200 Subject: [PATCH 006/812] Constructor argument renamed --- .../Magento/Framework/GraphQl/Query/QueryProcessor.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php index 0a23e4d00e8c7..e1c9c6d6dbdfe 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php @@ -28,14 +28,14 @@ class QueryProcessor /** * @param ExceptionFormatter $exceptionFormatter - * @param QueryComplexityLimiter $queryComplexityChecker + * @param QueryComplexityLimiter $queryComplexityLimiter */ public function __construct( ExceptionFormatter $exceptionFormatter, - QueryComplexityLimiter $queryComplexityChecker + QueryComplexityLimiter $queryComplexityLimiter ) { $this->exceptionFormatter = $exceptionFormatter; - $this->queryComplexityLimiter = $queryComplexityChecker; + $this->queryComplexityLimiter = $queryComplexityLimiter; } /** From 88fb39883b20bad5500e8a7e1fd492ed33bfecf9 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Mon, 30 Jul 2018 14:34:55 +0200 Subject: [PATCH 007/812] Fixed introspection disabling expression --- lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php index e1c9c6d6dbdfe..e3a2ea3fa753e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php @@ -55,7 +55,7 @@ public function process( array $variableValues = null, string $operationName = null ) : array { - $disableIntrospection = $this->exceptionFormatter->shouldShowDetail(); + $disableIntrospection = !$this->exceptionFormatter->shouldShowDetail(); $this->queryComplexityLimiter->execute($disableIntrospection); $rootValue = null; From 99b1d1d5397cc3fb97551699647a33717a6ed3f6 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Mon, 30 Jul 2018 14:53:14 +0200 Subject: [PATCH 008/812] Reduced limiting values --- app/code/Magento/GraphQl/etc/di.xml | 4 +- .../Framework/QueryComplexityLimiterTest.php | 173 +----------------- .../GraphQl/Query/QueryComplexityLimiter.php | 4 +- 3 files changed, 7 insertions(+), 174 deletions(-) diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 4aed25ac7bf4a..529280b7cbb6e 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -99,8 +99,8 @@ - 50 - 150 + 10 + 50 diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php index fe278eaef1914..c5f645a94472a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php @@ -86,109 +86,6 @@ public function testQueryComplexityIsLimited() id types } - categories { - id - position - level - url_key - url_path - product_count - breadcrumbs { - category_id - category_name - category_url_key - } - products { - items { - name - special_from_date - special_to_date - new_to_date - new_from_date - tier_price - manufacturer - thumbnail - sku - image - canonical_url - updated_at - created_at - categories { - id - position - level - url_key - url_path - product_count - breadcrumbs { - category_id - category_name - category_url_key - } - products { - items { - name - special_from_date - special_to_date - new_to_date - new_from_date - tier_price - manufacturer - sku - image - canonical_url - updated_at - created_at - categories { - id - position - level - url_key - url_path - product_count - breadcrumbs { - category_id - category_name - category_url_key - } - products { - items { - name - special_from_date - special_to_date - new_to_date - new_from_date - tier_price - manufacturer - sku - image - thumbnail - canonical_url - updated_at - created_at - categories { - id - position - level - url_key - url_path - product_count - default_sort_by - breadcrumbs { - category_id - category_name - category_url_key - } - } - } - } - } - } - } - } - } - } - } } } } @@ -201,7 +98,7 @@ public function testQueryComplexityIsLimited() } QUERY; - self::expectExceptionMessageRegExp('/Max query complexity should be 150 but got 151/'); + self::expectExceptionMessageRegExp('/Max query complexity should be 50 but got 62/'); $this->graphQlQuery($query); } @@ -238,71 +135,7 @@ public function testQueryDepthIsLimited() categories { products { items { - categories { - products { - items { - categories { - products { - items { - categories { - products { - items { - name, - categories { - products { - items { - categories { - products { - items { - categories{ - products { - items { - categories { - products { - items { - categories { - products { - items { - categories { - products { - items { - name, - categories { - products { - items { - categories { - name - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } + name } } } @@ -326,7 +159,7 @@ public function testQueryDepthIsLimited() } } QUERY; - self::expectExceptionMessageRegExp('/Max query depth should be 50 but got 51/'); + self::expectExceptionMessageRegExp('/Max query depth should be 10 but got 20/'); $this->graphQlQuery($query); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index 993390f5cfd22..d2d9477e67b1e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -34,8 +34,8 @@ class QueryComplexityLimiter * @param int $queryComplexity */ public function __construct( - int $queryDepth = 50, - int $queryComplexity = 150 + int $queryDepth = 10, + int $queryComplexity = 50 ) { $this->queryDepth = $queryDepth; $this->queryComplexity = $queryComplexity; From 9f47f05a36333e749e150c1bfc6c42cc4acbf5eb Mon Sep 17 00:00:00 2001 From: Navarr Barnier Date: Tue, 31 Jul 2018 13:43:37 -0400 Subject: [PATCH 009/812] Add Value and ValueInterface to Magento Framework's public API These classes are necessary/useful for creating a backend source for a Magento Configuration field. As such they should be reliable and part of the public API. --- lib/internal/Magento/Framework/App/Config/Value.php | 2 ++ lib/internal/Magento/Framework/App/Config/ValueInterface.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index c85b484d51ce2..e6923caa3d28c 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -17,6 +17,8 @@ * @method string getValue() * @method \Magento\Framework\App\Config\ValueInterface setValue(string $value) * + * @api + * * @SuppressWarnings(PHPMD.NumberOfChildren) */ class Value extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\App\Config\ValueInterface diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index 1e0747acc36f2..ab6a34c4274bd 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -9,7 +9,7 @@ /** * Interface \Magento\Framework\App\Config\ValueInterface - * + * @api */ interface ValueInterface { From a541c33264b1dca39f0fe62cc513cef7b160cf90 Mon Sep 17 00:00:00 2001 From: Navarr Barnier Date: Tue, 31 Jul 2018 16:23:40 -0400 Subject: [PATCH 010/812] Add ReadFactory and WriteFactory to Magento's public API These classes are necessary/useful for creating instances of ReadInterface and WriteInterface using the public API. --- .../Magento/Framework/Filesystem/File/ReadFactory.php | 6 +++++- .../Magento/Framework/Filesystem/File/WriteFactory.php | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php b/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php index 38b581da752b7..5d9badf42073f 100644 --- a/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php +++ b/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php @@ -8,6 +8,10 @@ use Magento\Framework\Filesystem\DriverInterface; use Magento\Framework\Filesystem\DriverPool; +/** + * Opens a file for reading + * @api + */ class ReadFactory { /** @@ -28,7 +32,7 @@ public function __construct(DriverPool $driverPool) } /** - * Create a readable file + * Create a {@see ReaderInterface} * * @param string $path * @param DriverInterface|string $driver Driver or driver code diff --git a/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php b/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php index a45d6a62488f6..af2a43ceaedc3 100644 --- a/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php +++ b/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php @@ -8,6 +8,10 @@ use Magento\Framework\Filesystem\DriverInterface; use Magento\Framework\Filesystem\DriverPool; +/** + * Opens a file for reading and/or writing + * @api + */ class WriteFactory extends ReadFactory { /** @@ -29,12 +33,12 @@ public function __construct(DriverPool $driverPool) } /** - * Create a readable file. + * Create a {@see WriterInterface} * * @param string $path * @param DriverInterface|string $driver Driver or driver code * @param string $mode [optional] - * @return Write + * @return WriteInterface */ public function create($path, $driver, $mode = 'r') { From 2a3562f77e816688c1e25c9ea342dc82456ecf42 Mon Sep 17 00:00:00 2001 From: Navarr Barnier Date: Tue, 31 Jul 2018 16:30:23 -0400 Subject: [PATCH 011/812] Add directory WriteInterface and ReadInterface --- .../Magento/Framework/Filesystem/Directory/ReadInterface.php | 2 +- .../Magento/Framework/Filesystem/Directory/WriteInterface.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php b/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php index 5519245ec24b4..61108c64dda44 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php @@ -7,7 +7,7 @@ /** * Interface \Magento\Framework\Filesystem\Directory\ReadInterface - * + * @api */ interface ReadInterface { diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php b/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php index c72651a78dad3..186cbcb81bff2 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php @@ -7,7 +7,7 @@ /** * Interface \Magento\Framework\Filesystem\Directory\WriteInterface - * + * @api */ interface WriteInterface extends ReadInterface { From e671008cb2a261842823d64dd4ea20040fafcc5f Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak Date: Tue, 14 Aug 2018 15:26:27 +0300 Subject: [PATCH 012/812] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Template fixed: added checking of all gift options. Also added possibility to change order level options visibility from other modules. --- .../GiftMessage/Block/Message/Inline.php | 21 +++++++++++++++++-- .../view/frontend/templates/inline.phtml | 9 +++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/GiftMessage/Block/Message/Inline.php b/app/code/Magento/GiftMessage/Block/Message/Inline.php index e5b80848661fd..1a874cb5ea4ae 100644 --- a/app/code/Magento/GiftMessage/Block/Message/Inline.php +++ b/app/code/Magento/GiftMessage/Block/Message/Inline.php @@ -238,7 +238,7 @@ public function getMessage($entity = null) */ public function getItems() { - if (!$this->getData('items')) { + if (!$this->hasData('items')) { $items = []; $entityItems = $this->getEntity()->getAllItems(); @@ -325,6 +325,23 @@ public function getEscaped($value, $defaultValue = '') return $this->escapeHtml(trim($value) != '' ? $value : $defaultValue); } + /** + * Check availability of order level functionality + * + * @return bool + */ + public function isOrderLevelAvailable() + { + $entity = $this->getEntity(); + if (!$entity->hasIsGiftOptionsAvailable()) { + $this->_eventManager->dispatch('gift_options_prepare', ['entity' => $entity]); + if (!$entity->getIsGiftOptionsAvailable()) { + $entity->setIsGiftOptionsAvailable($this->isMessagesAvailable()); + } + } + return $entity->getIsGiftOptionsAvailable(); + } + /** * Check availability of giftmessages on order level * @@ -355,7 +372,7 @@ public function isItemMessagesAvailable($item) protected function _toHtml() { // render HTML when messages are allowed for order or for items only - if ($this->isItemsAvailable() || $this->isMessagesAvailable()) { + if ($this->isItemsAvailable() || $this->isOrderLevelAvailable()) { return parent::_toHtml(); } return ''; diff --git a/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml b/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml index dec54cfeb9df9..8c58959be15b7 100644 --- a/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml +++ b/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml @@ -18,7 +18,7 @@
    - isMessagesAvailable()): ?> + isOrderLevelAvailable()): ?>
    getEntityHasMessage()): ?> checked="checked" class="checkbox" /> @@ -28,6 +28,7 @@
    + isMessagesAvailable()): ?>
    - + isItemsAvailable()): ?>
    @@ -152,6 +154,7 @@
    + isOrderLevelAvailable()): ?>
    getEntityHasMessage()): ?> checked="checked" class="checkbox" /> @@ -192,7 +195,7 @@
    - + isItemsAvailable()): ?>
    From ddb642c10e70c1acab5683beaf8d7d5b4b5e8ffd Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak Date: Mon, 20 Aug 2018 11:05:50 +0300 Subject: [PATCH 013/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Moved saving toolbar params to session from block to model. Save params before generating layout xml. --- .../Block/Product/ProductList/Toolbar.php | 43 ++++- .../Catalog/Controller/Category/View.php | 12 +- .../Product/ProductList/ToolbarMemorizer.php | 161 ++++++++++++++++++ 3 files changed, 208 insertions(+), 8 deletions(-) create mode 100644 app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index 0b8d2d6c89e72..0e971dcb5b9f5 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -7,6 +7,7 @@ use Magento\Catalog\Helper\Product\ProductList; use Magento\Catalog\Model\Product\ProductList\Toolbar as ToolbarModel; +use Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer; /** * Product list toolbar @@ -77,6 +78,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template /** * @var bool $_paramsMemorizeAllowed + * @deprecated */ protected $_paramsMemorizeAllowed = true; @@ -96,6 +98,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template * Catalog session * * @var \Magento\Catalog\Model\Session + * @deprecated */ protected $_catalogSession; @@ -104,6 +107,11 @@ class Toolbar extends \Magento\Framework\View\Element\Template */ protected $_toolbarModel; + /** + * @var ToolbarMemorizer + */ + private $toolbarMemorizer; + /** * @var ProductList */ @@ -119,6 +127,11 @@ class Toolbar extends \Magento\Framework\View\Element\Template */ protected $_postDataHelper; + /** + * @var \Magento\Framework\App\Http\Context + */ + private $httpContext; + /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Catalog\Model\Session $catalogSession @@ -127,6 +140,8 @@ class Toolbar extends \Magento\Framework\View\Element\Template * @param \Magento\Framework\Url\EncoderInterface $urlEncoder * @param ProductList $productListHelper * @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper + * @param ToolbarMemorizer|null $toolbarMemorizer + * @param \Magento\Framework\App\Http\Context|null $httpContext * @param array $data */ public function __construct( @@ -137,6 +152,8 @@ public function __construct( \Magento\Framework\Url\EncoderInterface $urlEncoder, ProductList $productListHelper, \Magento\Framework\Data\Helper\PostHelper $postDataHelper, + ToolbarMemorizer $toolbarMemorizer = null, + \Magento\Framework\App\Http\Context $httpContext = null, array $data = [] ) { $this->_catalogSession = $catalogSession; @@ -145,6 +162,12 @@ public function __construct( $this->urlEncoder = $urlEncoder; $this->_productListHelper = $productListHelper; $this->_postDataHelper = $postDataHelper; + $this->toolbarMemorizer = $toolbarMemorizer ?: \Magento\Framework\App\ObjectManager::getInstance()->get( + ToolbarMemorizer::class + ); + $this->httpContext = $httpContext ?: \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\App\Http\Context::class + ); parent::__construct($context, $data); } @@ -152,6 +175,7 @@ public function __construct( * Disable list state params memorizing * * @return $this + * @deprecated */ public function disableParamsMemorizing() { @@ -165,6 +189,7 @@ public function disableParamsMemorizing() * @param string $param parameter name * @param mixed $value parameter value * @return $this + * @deprecated */ protected function _memorizeParam($param, $value) { @@ -244,13 +269,13 @@ public function getCurrentOrder() $defaultOrder = $keys[0]; } - $order = $this->_toolbarModel->getOrder(); + $order = $this->toolbarMemorizer->getOrder(); if (!$order || !isset($orders[$order])) { $order = $defaultOrder; } if ($order != $defaultOrder) { - $this->_memorizeParam('sort_order', $order); + $this->httpContext->setValue(ToolbarModel::ORDER_PARAM_NAME, $order, $defaultOrder); } $this->setData('_current_grid_order', $order); @@ -270,13 +295,13 @@ public function getCurrentDirection() } $directions = ['asc', 'desc']; - $dir = strtolower($this->_toolbarModel->getDirection()); + $dir = strtolower($this->toolbarMemorizer->getDirection()); if (!$dir || !in_array($dir, $directions)) { $dir = $this->_direction; } if ($dir != $this->_direction) { - $this->_memorizeParam('sort_direction', $dir); + $this->httpContext->setValue(ToolbarModel::DIRECTION_PARAM_NAME, $dir, $this->_direction); } $this->setData('_current_grid_direction', $dir); @@ -412,11 +437,15 @@ public function getCurrentMode() return $mode; } $defaultMode = $this->_productListHelper->getDefaultViewMode($this->getModes()); - $mode = $this->_toolbarModel->getMode(); + $mode = $this->toolbarMemorizer->getMode(); if (!$mode || !isset($this->_availableMode[$mode])) { $mode = $defaultMode; } + if ($mode != $defaultMode) { + $this->httpContext->setValue(ToolbarModel::MODE_PARAM_NAME, $mode, $defaultMode); + } + $this->setData('_current_grid_mode', $mode); return $mode; } @@ -568,13 +597,13 @@ public function getLimit() $defaultLimit = $keys[0]; } - $limit = $this->_toolbarModel->getLimit(); + $limit = $this->toolbarMemorizer->getLimit(); if (!$limit || !isset($limits[$limit])) { $limit = $defaultLimit; } if ($limit != $defaultLimit) { - $this->_memorizeParam('limit_page', $limit); + $this->httpContext->setValue(ToolbarModel::LIMIT_PARAM_NAME, $limit, $defaultLimit); } $this->setData('_current_limit', $limit); diff --git a/app/code/Magento/Catalog/Controller/Category/View.php b/app/code/Magento/Catalog/Controller/Category/View.php index 226e572505076..d451357a7c129 100644 --- a/app/code/Magento/Catalog/Controller/Category/View.php +++ b/app/code/Magento/Catalog/Controller/Category/View.php @@ -8,6 +8,7 @@ use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Catalog\Model\Layer\Resolver; +use Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\View\Result\PageFactory; @@ -69,6 +70,11 @@ class View extends \Magento\Framework\App\Action\Action */ protected $categoryRepository; + /** + * @var ToolbarMemorizer + */ + private $toolbarMemorizer; + /** * Constructor * @@ -82,6 +88,7 @@ class View extends \Magento\Framework\App\Action\Action * @param \Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory * @param Resolver $layerResolver * @param CategoryRepositoryInterface $categoryRepository + * @param ToolbarMemorizer|null $toolbarMemorizer * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -94,7 +101,8 @@ public function __construct( PageFactory $resultPageFactory, \Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory, Resolver $layerResolver, - CategoryRepositoryInterface $categoryRepository + CategoryRepositoryInterface $categoryRepository, + ToolbarMemorizer $toolbarMemorizer = null ) { parent::__construct($context); $this->_storeManager = $storeManager; @@ -106,6 +114,7 @@ public function __construct( $this->resultForwardFactory = $resultForwardFactory; $this->layerResolver = $layerResolver; $this->categoryRepository = $categoryRepository; + $this->toolbarMemorizer = $toolbarMemorizer ?: $context->getObjectManager()->get(ToolbarMemorizer::class); } /** @@ -130,6 +139,7 @@ protected function _initCategory() } $this->_catalogSession->setLastVisitedCategoryId($category->getId()); $this->_coreRegistry->register('current_category', $category); + $this->toolbarMemorizer->memorizeParams(); try { $this->_eventManager->dispatch( 'catalog_controller_category_init_after', diff --git a/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php b/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php new file mode 100644 index 0000000000000..1ff63a0fa3448 --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php @@ -0,0 +1,161 @@ +toolbarModel = $toolbarModel; + $this->catalogSession = $catalogSession; + } + + /** + * Get sort order + * + * @return string|bool + */ + public function getOrder() + { + if ($this->order === null) { + $this->order = $this->toolbarModel->getOrder() ?? + $this->catalogSession->getData(Toolbar::ORDER_PARAM_NAME); + } + return $this->order; + } + + /** + * Get sort direction + * + * @return string|bool + */ + public function getDirection() + { + if ($this->direction === null) { + $this->direction = $this->toolbarModel->getDirection() ?? + $this->catalogSession->getData(Toolbar::DIRECTION_PARAM_NAME); + } + return $this->direction; + } + + /** + * Get sort mode + * + * @return string|bool + */ + public function getMode() + { + if ($this->mode === null) { + $this->mode = $this->toolbarModel->getMode() ?? + $this->catalogSession->getData(Toolbar::MODE_PARAM_NAME); + } + return $this->mode; + } + + /** + * Get products per page limit + * + * @return string|bool + */ + public function getLimit() + { + if ($this->limit === null) { + $this->limit = $this->toolbarModel->getLimit() ?? + $this->catalogSession->getData(Toolbar::LIMIT_PARAM_NAME); + } + return $this->limit; + } + + /** + * Disable list state params memorizing + * + * @return $this + */ + public function disableParamsMemorizing() + { + $this->paramsMemorizeAllowed = false; + return $this; + } + + /** + * Method to save all catalog parameters in catalog session + * + * @return void + */ + public function memorizeParams() + { + $this->memorizeParam(Toolbar::ORDER_PARAM_NAME, $this->getOrder()) + ->memorizeParam(Toolbar::DIRECTION_PARAM_NAME, $this->getDirection()) + ->memorizeParam(Toolbar::MODE_PARAM_NAME, $this->getMode()) + ->memorizeParam(Toolbar::LIMIT_PARAM_NAME, $this->getLimit()); + } + + /** + * Memorize parameter value for session + * + * @param string $param parameter name + * @param mixed $value parameter value + * @return $this + */ + private function memorizeParam($param, $value) + { + if ($value && $this->paramsMemorizeAllowed && + !$this->catalogSession->getParamsMemorizeDisabled() && + $this->catalogSession->getData($param) != $value + ) { + $this->catalogSession->setData($param, $value); + } + return $this; + } +} From 9ef1afe6ae278615c23c0deb73b9fdd5f16b1b07 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak Date: Tue, 28 Aug 2018 17:56:51 +0300 Subject: [PATCH 014/812] MAGETWO-91563: Gift wrapping selection does not display in shopping cart - Used right model to observe gift wrapping options. --- .../GiftMessage/view/frontend/web/js/view/gift-message.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GiftMessage/view/frontend/web/js/view/gift-message.js b/app/code/Magento/GiftMessage/view/frontend/web/js/view/gift-message.js index d025f6974f35e..4c455c83a77a9 100644 --- a/app/code/Magento/GiftMessage/view/frontend/web/js/view/gift-message.js +++ b/app/code/Magento/GiftMessage/view/frontend/web/js/view/gift-message.js @@ -31,8 +31,9 @@ define([ this.itemId = this.itemId || 'orderLevel'; model = new GiftMessage(this.itemId); - giftOptions.addOption(model); this.model = model; + this.isResultBlockVisible(); + giftOptions.addOption(model); this.model.getObservable('isClear').subscribe(function (value) { if (value == true) { //eslint-disable-line eqeqeq @@ -40,8 +41,6 @@ define([ self.model.getObservable('alreadyAdded')(true); } }); - - this.isResultBlockVisible(); }, /** From f2e053a7d6e87252ae526049b2253566d19ee0a7 Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan Date: Tue, 28 Aug 2018 19:23:23 +0400 Subject: [PATCH 015/812] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Add automated test --- .../Section/StoreFrontShoppingCartSection.xml | 15 +++++ .../CleanConfigsForGiftOptionsActionGroup.xml | 32 +++++++++++ ...ftWrappingForOrderItemsOnlyActionGroup.xml | 32 +++++++++++ .../Mftf/Section/AdminSalesConfigSection.xml | 16 +++++- .../CheckingGiftOptionsActionGroup.xml | 23 ++++++++ .../Section/GiftOptionsOnFrontSection.xml | 13 +++++ .../StoreFrontCheckingGiftOptionsTest.xml | 57 +++++++++++++++++++ 7 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml create mode 100644 app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml create mode 100644 app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml new file mode 100644 index 0000000000000..303c5e526423f --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml @@ -0,0 +1,15 @@ + + + + +
    + + +
    +
    diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml new file mode 100644 index 0000000000000..72d88b13736cc --- /dev/null +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml new file mode 100644 index 0000000000000..8f5b491575e95 --- /dev/null +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml b/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml index 4897e8415c1b8..aefb7c5441c5b 100644 --- a/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml +++ b/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml @@ -5,9 +5,23 @@ * See COPYING.txt for license details. */ --> - +
    + + + + + + + + + + + + + +
    \ No newline at end of file diff --git a/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml b/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml new file mode 100644 index 0000000000000..05dad757e287f --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml b/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml new file mode 100644 index 0000000000000..9856f009197c1 --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml @@ -0,0 +1,13 @@ + + + +
    + + +
    +
    \ No newline at end of file diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml b/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml new file mode 100644 index 0000000000000..7b4bd56ae74e8 --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml @@ -0,0 +1,57 @@ + + + + + + + + + + <description value="Admin should be able to control gift options"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94209"/> + <group value="Gift"/> + </annotations> + <before> + <createData stepKey="category" entity="SimpleSubCategory"/> + <createData stepKey="product1" entity="SimpleProduct"> + <requiredEntity createDataKey="category"/> + </createData> + <createData stepKey="product2" entity="SimpleProduct"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="customer"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup" stepKey="configureGiftOptions"/> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount"> + <argument name="Customer" value="$$customer$$"/> + </actionGroup> + </before> + + <amOnPage url="$$product1.name$$.html" stepKey="goToProduct1"/> + <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProduct1"> + <argument name="productName" value="$$product1.name$$"/> + </actionGroup> + <amOnPage url="$$product2.name$$.html" stepKey="goToProduct2"/> + <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProduct2"> + <argument name="productName" value="$$product2.name$$"/> + </actionGroup> + <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="openCart"/> + <actionGroup ref="CheckingGiftOptionsActionGroup" stepKey="checkGiftOptions"/> + + <after> + <actionGroup ref="CleanConfigsForGiftOptionsActionGroup" stepKey="cleanGiftOptionsConfigs"/> + <deleteData stepKey="deleteCategory" createDataKey="category"/> + <deleteData stepKey="deleteProduct1" createDataKey="product1"/> + <deleteData stepKey="deleteProduct2" createDataKey="product2"/> + <deleteData stepKey="deleteCustomer" createDataKey="customer"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + </after> + </test> +</tests> From adb3af29f2fc435b193338a80d873689cac82a1d Mon Sep 17 00:00:00 2001 From: Arnoud Beekman <arnoud.beekman@mediact.nl> Date: Sun, 26 Aug 2018 20:41:13 +0200 Subject: [PATCH 016/812] Optimize code to remove phpmd suppress warnings By making the order of some checks more efficient the suppress warnings in these two files about CyclomaticComplexity and NPathComplexity. --- .../Magento/Customer/Model/Metadata/Form/Text.php | 11 +++++------ app/code/Magento/Eav/Model/Attribute/Data/Text.php | 13 ++++++------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Customer/Model/Metadata/Form/Text.php b/app/code/Magento/Customer/Model/Metadata/Form/Text.php index c8b9a1e46a127..dcd3bc93569a4 100644 --- a/app/code/Magento/Customer/Model/Metadata/Form/Text.php +++ b/app/code/Magento/Customer/Model/Metadata/Form/Text.php @@ -52,8 +52,6 @@ public function extractValue(\Magento\Framework\App\RequestInterface $request) /** * @inheritdoc - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) */ public function validateValue($value) { @@ -66,12 +64,12 @@ public function validateValue($value) $value = $this->_value; } - if ($attribute->isRequired() && empty($value) && $value !== '0') { - $errors[] = __('"%1" is a required value.', $label); + if (!$attribute->isRequired() && empty($value)) { + return true; } - if (!$errors && !$attribute->isRequired() && empty($value)) { - return true; + if (empty($value) && $value !== '0') { + $errors[] = __('"%1" is a required value.', $label); } $errors = $this->validateLength($value, $attribute, $errors); @@ -80,6 +78,7 @@ public function validateValue($value) if ($result !== true) { $errors = array_merge($errors, $result); } + if (count($errors) == 0) { return true; } diff --git a/app/code/Magento/Eav/Model/Attribute/Data/Text.php b/app/code/Magento/Eav/Model/Attribute/Data/Text.php index f81fb2affd3b3..a26a92df385f2 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/Text.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/Text.php @@ -55,8 +55,7 @@ public function extractValue(RequestInterface $request) * * @param array|string $value * @return bool|array - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) + * @throws \Magento\Framework\Exception\LocalizedException */ public function validateValue($value) { @@ -68,13 +67,13 @@ public function validateValue($value) $value = $this->getEntity()->getDataUsingMethod($attribute->getAttributeCode()); } - if ($attribute->getIsRequired() && empty($value) && $value !== '0') { - $label = __($attribute->getStoreLabel()); - $errors[] = __('"%1" is a required value.', $label); + if (!$attribute->isRequired() && empty($value)) { + return true; } - if (!$errors && !$attribute->getIsRequired() && empty($value)) { - return true; + if (empty($value) && $value !== '0') { + $label = __($attribute->getStoreLabel()); + $errors[] = __('"%1" is a required value.', $label); } $result = $this->validateLength($attribute, $value); From ea9168570ae0f2d5bcf1911b13b46b760a9cb0eb Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Fri, 31 Aug 2018 14:42:59 +0300 Subject: [PATCH 017/812] MAGETWO-91628: Bundle product price doubled when switching currency - Fixed an issue with quote item options relates to a bundled products. --- .../Magento/Bundle/Model/Product/Type.php | 2 +- .../Plugin/UpdatePriceInQuoteItemOptions.php | 55 +++++++++++++++++++ app/code/Magento/Bundle/etc/di.xml | 3 + 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Bundle/Plugin/UpdatePriceInQuoteItemOptions.php diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php index 17ecba545efad..c5f3aa0a84995 100644 --- a/app/code/Magento/Bundle/Model/Product/Type.php +++ b/app/code/Magento/Bundle/Model/Product/Type.php @@ -735,7 +735,7 @@ protected function _prepareProduct(\Magento\Framework\DataObject $buyRequest, $p $price = $product->getPriceModel() ->getSelectionFinalTotalPrice($product, $selection, 0, $qty); $attributes = [ - 'price' => $this->priceCurrency->convert($price), + 'price' => $price, 'qty' => $qty, 'option_label' => $selection->getOption() ->getTitle(), diff --git a/app/code/Magento/Bundle/Plugin/UpdatePriceInQuoteItemOptions.php b/app/code/Magento/Bundle/Plugin/UpdatePriceInQuoteItemOptions.php new file mode 100644 index 0000000000000..d5aafb8ad2b61 --- /dev/null +++ b/app/code/Magento/Bundle/Plugin/UpdatePriceInQuoteItemOptions.php @@ -0,0 +1,55 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Bundle\Plugin; + +use Magento\Quote\Model\Quote\Item as OrigQuoteItem; +use Magento\Quote\Model\Quote\Item\AbstractItem; +use Magento\Framework\Serialize\SerializerInterface; + +/** + * Update prices stored in quote item options after calculating quote item's totals + */ +class UpdatePriceInQuoteItemOptions +{ + /** + * @var SerializerInterface + */ + private $serializer; + + /** + * @param SerializerInterface $serializer + */ + public function __construct(SerializerInterface $serializer) + { + $this->serializer = $serializer; + } + + /** + * Update price on quote item options level + * + * @param OrigQuoteItem $subject + * @param AbstractItem $result + * @return AbstractItem + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterCalcRowTotal(OrigQuoteItem $subject, AbstractItem $result) + { + $bundleAttributes = $result->getProduct()->getCustomOption('bundle_selection_attributes'); + if ($bundleAttributes !== null) { + $actualPrice = $result->getPrice(); + $parsedValue = $this->serializer->unserialize($bundleAttributes->getValue()); + if (is_array($parsedValue) && array_key_exists('price', $parsedValue)) { + $parsedValue['price'] = $actualPrice; + } + $bundleAttributes->setValue($this->serializer->serialize($parsedValue)); + } + + return $result; + } +} diff --git a/app/code/Magento/Bundle/etc/di.xml b/app/code/Magento/Bundle/etc/di.xml index 733b089dccd4b..6f0cc04790cc2 100644 --- a/app/code/Magento/Bundle/etc/di.xml +++ b/app/code/Magento/Bundle/etc/di.xml @@ -123,6 +123,9 @@ </argument> </arguments> </type> + <type name="Magento\Quote\Model\Quote\Item"> + <plugin name="update_price_for_bundle_in_quote_item_option" type="Magento\Bundle\Plugin\UpdatePriceInQuoteItemOptions"/> + </type> <type name="Magento\Quote\Model\Quote\Item\ToOrderItem"> <plugin name="append_bundle_data_to_order" type="Magento\Bundle\Model\Plugin\QuoteItem"/> </type> From 1ff16642855a313b3b8e4a7a9a6e836c09769c69 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <dhorytskyi@magento.com> Date: Mon, 3 Sep 2018 18:33:15 +0300 Subject: [PATCH 018/812] MAGETWO-94424: [2.3] Wrong product and shipping prices are applying on admin orders --- app/code/Magento/Store/Model/Store.php | 20 ++-- .../Store/Test/Unit/Model/StoreTest.php | 98 ++++++++++++++++++- 2 files changed, 103 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Store/Model/Store.php b/app/code/Magento/Store/Model/Store.php index af25957257421..32c9a78448428 100644 --- a/app/code/Magento/Store/Model/Store.php +++ b/app/code/Magento/Store/Model/Store.php @@ -902,23 +902,17 @@ public function setCurrentCurrencyCode($code) */ public function getCurrentCurrencyCode() { + $availableCurrencyCodes = \array_values($this->getAvailableCurrencyCodes(true)); // try to get currently set code among allowed - $code = $this->_httpContext->getValue(Context::CONTEXT_CURRENCY); - $code = $code === null ? $this->_getSession()->getCurrencyCode() : $code; - if (empty($code)) { + $code = $this->_httpContext->getValue(Context::CONTEXT_CURRENCY) ?? $this->_getSession()->getCurrencyCode(); + if (empty($code) || !\in_array($code, $availableCurrencyCodes)) { $code = $this->getDefaultCurrencyCode(); - } - if (in_array($code, $this->getAvailableCurrencyCodes(true))) { - return $code; + if (!\in_array($code, $availableCurrencyCodes) && !empty($availableCurrencyCodes)) { + $code = $availableCurrencyCodes[0]; + } } - // take first one of allowed codes - $codes = array_values($this->getAvailableCurrencyCodes(true)); - if (empty($codes)) { - // return default code, if no codes specified at all - return $this->getDefaultCurrencyCode(); - } - return array_shift($codes); + return $code; } /** diff --git a/app/code/Magento/Store/Test/Unit/Model/StoreTest.php b/app/code/Magento/Store/Test/Unit/Model/StoreTest.php index f98cf5d892e07..f4a5010e51b88 100644 --- a/app/code/Magento/Store/Test/Unit/Model/StoreTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/StoreTest.php @@ -3,11 +3,11 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Store\Test\Unit\Model; use Magento\Framework\App\Config\ReinitableConfigInterface; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Session\SessionManagerInterface; use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\Store; @@ -38,6 +38,16 @@ class StoreTest extends \PHPUnit\Framework\TestCase */ protected $filesystemMock; + /** + * @var ReinitableConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $configMock; + + /** + * @var SessionManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $sessionMock; + /** * @var \Magento\Framework\Url\ModifierInterface|\PHPUnit_Framework_MockObject_MockObject */ @@ -61,12 +71,22 @@ protected function setUp() 'isSecure', 'getServer', ]); + $this->filesystemMock = $this->getMockBuilder(\Magento\Framework\Filesystem::class) ->disableOriginalConstructor() ->getMock(); + $this->configMock = $this->getMockBuilder(ReinitableConfigInterface::class) + ->getMock(); + $this->sessionMock = $this->getMockBuilder(SessionManagerInterface::class) + ->setMethods(['getCurrencyCode']) + ->getMockForAbstractClass(); $this->store = $this->objectManagerHelper->getObject( \Magento\Store\Model\Store::class, - ['filesystem' => $this->filesystemMock] + [ + 'filesystem' => $this->filesystemMock, + 'config' => $this->configMock, + 'session' => $this->sessionMock, + ] ); $this->urlModifierMock = $this->createMock(\Magento\Framework\Url\ModifierInterface::class); @@ -694,6 +714,80 @@ public function testGetScopeTypeName() $this->assertEquals('Store View', $this->store->getScopeTypeName()); } + /** + * @param array $availableCodes + * @param string $currencyCode + * @param string $defaultCode + * @param string $expectedCode + * @return void + * @dataProvider currencyCodeDataProvider + */ + public function testGetCurrentCurrencyCode( + array $availableCodes, + string $currencyCode, + string $defaultCode, + string $expectedCode + ): void { + $this->store->setData('available_currency_codes', $availableCodes); + $this->sessionMock->method('getCurrencyCode') + ->willReturn($currencyCode); + $this->configMock->method('getValue') + ->with(\Magento\Directory\Model\Currency::XML_PATH_CURRENCY_DEFAULT) + ->willReturn($defaultCode); + + $code = $this->store->getCurrentCurrencyCode(); + $this->assertEquals($expectedCode, $code); + } + + /** + * @return array + */ + public function currencyCodeDataProvider(): array + { + return [ + [ + [ + 'USD', + ], + 'USD', + 'USD', + 'USD', + ], + [ + [ + 'USD', + 'EUR', + ], + 'EUR', + 'USD', + 'EUR', + ], + [ + [ + 'EUR', + 'USD', + ], + 'GBP', + 'USD', + 'USD', + ], + [ + [ + 'USD', + ], + 'GBP', + 'EUR', + 'USD', + ], + [ + [], + 'GBP', + 'EUR', + 'EUR', + ], + ]; + } + /** * @param \Magento\Store\Model\Store $model */ From 38d5547049a0f2f6bf83b016b1af55961ccd753c Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Tue, 4 Sep 2018 13:47:33 +0400 Subject: [PATCH 019/812] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Updated automated test --- .../CleanConfigsForGiftOptionsActionGroup.xml | 32 --------------- ...ftWrappingForOrderItemsOnlyActionGroup.xml | 32 --------------- .../Test/Mftf/Data/GiftOptionsData.xml | 40 +++++++++++++++++++ .../Test/Mftf/Metadata/gift_options-meta.xml | 31 ++++++++++++++ .../StoreFrontCheckingGiftOptionsTest.xml | 6 ++- 5 files changed, 75 insertions(+), 66 deletions(-) delete mode 100644 app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml delete mode 100644 app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml deleted file mode 100644 index 72d88b13736cc..0000000000000 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/CleanConfigsForGiftOptionsActionGroup.xml +++ /dev/null @@ -1,32 +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="CleanConfigsForGiftOptionsActionGroup"> - <amOnPage url="{{AdminSalesConfigPage.url('')}}" stepKey="amOnSalesConfigPage"/> - <waitForPageLoad stepKey="waitForConfigPage" time="5"/> - <conditionalClick selector="{{AdminSalesConfigSection.giftOptions}}" - dependentSelector="{{AdminSalesConfigSection.allowGiftWrappingForOrderItems}}" visible="false" - stepKey="openGiftOptionsIfItIsClosed"/> - <waitForPageLoad stepKey="waitForGiftOptions" time="2"/> - <click stepKey="openOrderLevel" selector="{{AdminSalesConfigSection.allowGiftWrappingOnOrderLevel}}"/> - <click stepKey="chooseYesForOrderLevel" selector="{{AdminSalesConfigSection.levelYes}}"/> - <click stepKey="openOrderItems" selector="{{AdminSalesConfigSection.allowGiftWrappingForOrderItems}}"/> - <click stepKey="chooseYesForOrderItems" selector="{{AdminSalesConfigSection.itemsYes}}"/> - <click stepKey="openGiftReceipt" selector="{{AdminSalesConfigSection.allowGiftReceipt}}"/> - <click stepKey="chooseYesForReceipt" selector="{{AdminSalesConfigSection.receiptYes}}"/> - <click stepKey="openPrintedCard" selector="{{AdminSalesConfigSection.allowPrintedCard}}"/> - <click stepKey="chooseYesPrintedCard" selector="{{AdminSalesConfigSection.printedCardYes}}"/> - <click stepKey="closeGiftOptions" selector="{{AdminSalesConfigSection.giftOptions}}"/> - <click stepKey="save" selector="{{AdminConfigSection.saveButton}}"/> - <waitForPageLoad stepKey="waitForSevConfigs" time="5"/> - <see stepKey="seeSuccessMessage" userInput="You saved the configuration."/> - </actionGroup> -</actionGroups> - diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml deleted file mode 100644 index 8f5b491575e95..0000000000000 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup.xml +++ /dev/null @@ -1,32 +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="ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup"> - <amOnPage url="{{AdminSalesConfigPage.url('')}}" stepKey="amOnSalesConfigPage"/> - <waitForPageLoad stepKey="waitForConfigPage" time="5"/> - <scrollTo stepKey="scrollToGiftOptions" selector="{{AdminSalesConfigSection.giftOptions}}"/> - <conditionalClick selector="{{AdminSalesConfigSection.giftOptions}}" - dependentSelector="{{AdminSalesConfigSection.allowGiftWrappingForOrderItems}}" visible="false" - stepKey="openGiftOptionsIfItIsClosed"/> - <waitForPageLoad stepKey="waitForGiftOptions" time="2"/> - <click stepKey="openOrderLevel" selector="{{AdminSalesConfigSection.allowGiftWrappingOnOrderLevel}}"/> - <click stepKey="chooseNoForOrderLevel" selector="{{AdminSalesConfigSection.levelNo}}"/> - <click stepKey="openOrderItems" selector="{{AdminSalesConfigSection.allowGiftWrappingForOrderItems}}"/> - <click stepKey="chooseYesForOrderItems" selector="{{AdminSalesConfigSection.itemsYes}}"/> - <click stepKey="openGiftReceipt" selector="{{AdminSalesConfigSection.allowGiftReceipt}}"/> - <click stepKey="chooseNoForReceipt" selector="{{AdminSalesConfigSection.receiptNo}}"/> - <click stepKey="openPrintedCard" selector="{{AdminSalesConfigSection.allowPrintedCard}}"/> - <click stepKey="chooseNoPrintedCard" selector="{{AdminSalesConfigSection.printedCardNo}}"/> - <click stepKey="save" selector="{{AdminConfigSection.saveButton}}"/> - <waitForPageLoad stepKey="waitForSevConfigs" time="5"/> - <see stepKey="seeSuccessMessage" userInput="You saved the configuration."/> - </actionGroup> -</actionGroups> - diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml b/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml new file mode 100644 index 0000000000000..b2bc71b5b7a7b --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml @@ -0,0 +1,40 @@ +<?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="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="ConfigAllowGiftWrappingForOrderItemsOnly" type="gift_options_config_state"> + <requiredEntity type="wrapping_allow_order">wrappingAllowOrder</requiredEntity> + <requiredEntity type="allow_gift_receipt">allowGiftReceipt</requiredEntity> + <requiredEntity type="allow_printed_card">allowPrintedCard</requiredEntity> + </entity> + <entity name="wrappingAllowOrder" type="wrapping_allow_order"> + <data key="value">0</data> + </entity> + <entity name="allowGiftReceipt" type="allow_gift_receipt"> + <data key="value">0</data> + </entity> + <entity name="allowPrintedCard" type="allow_printed_card"> + <data key="value">0</data> + </entity> + + <entity name="DefaultConfigGiftOptions" type="gift_options_config_state"> + <requiredEntity type="wrapping_allow_order">defaultWrappingAllowOrder</requiredEntity> + <requiredEntity type="allow_gift_receipt">defaultAllowGiftReceipt</requiredEntity> + <requiredEntity type="allow_printed_card">defaultAllowPrintedCard</requiredEntity> + </entity> + <entity name="defaultWrappingAllowOrder" type="wrapping_allow_order"> + <data key="value">1</data> + </entity> + <entity name="defaultAllowGiftReceipt" type="allow_gift_receipt"> + <data key="value">1</data> + </entity> + <entity name="defaultAllowPrintedCard" type="allow_printed_card"> + <data key="value">1</data> + </entity> +</entities> diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml b/app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml new file mode 100644 index 0000000000000..a32f5694f2470 --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml @@ -0,0 +1,31 @@ +<?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="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="SalesGiftOptionsConfigState" dataType="gift_options_config_state" type="create" auth="adminFormKey" url="/admin/system_config/save/section/sales/" method="POST"> + <object key="groups" dataType="gift_options_config_state"> + <object key="gift_options" dataType="gift_options_config_state"> + <object key="fields" dataType="gift_options_config_state"> + <object key="wrapping_allow_order" dataType="wrapping_allow_order"> + <field key="value">string</field> + </object> + <object key="wrapping_allow_items" dataType="wrapping_allow_items"> + <field key="value">string</field> + </object> + <object key="allow_gift_receipt" dataType="allow_gift_receipt"> + <field key="value">string</field> + </object> + <object key="allow_printed_card" dataType="allow_printed_card"> + <field key="value">string</field> + </object> + </object> + </object> + </object> + </operation> +</operations> diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml b/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml index 7b4bd56ae74e8..0bb5bf0e71fa8 100644 --- a/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml +++ b/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml @@ -27,11 +27,13 @@ <requiredEntity createDataKey="category"/> </createData> <createData entity="Simple_US_Customer" stepKey="customer"/> + <createData entity="ConfigAllowGiftWrappingForOrderItemsOnly" stepKey="configAllowGiftWrappingForOrderItemsOnly"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="ConfigAllowGiftWrappingForOrderItemsOnlyActionGroup" stepKey="configureGiftOptions"/> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount"> <argument name="Customer" value="$$customer$$"/> </actionGroup> + </before> <amOnPage url="$$product1.name$$.html" stepKey="goToProduct1"/> @@ -46,7 +48,7 @@ <actionGroup ref="CheckingGiftOptionsActionGroup" stepKey="checkGiftOptions"/> <after> - <actionGroup ref="CleanConfigsForGiftOptionsActionGroup" stepKey="cleanGiftOptionsConfigs"/> + <createData entity="DefaultConfigGiftOptions" stepKey="restoreDefaultConfigGiftOptions"/> <deleteData stepKey="deleteCategory" createDataKey="category"/> <deleteData stepKey="deleteProduct1" createDataKey="product1"/> <deleteData stepKey="deleteProduct2" createDataKey="product2"/> From 2a7cd23d460e8ff278730cafbf3a2a1f33ae2461 Mon Sep 17 00:00:00 2001 From: Oleksandr_Hodzevych <Oleksandr_Hodzevych@epam.com> Date: Mon, 3 Sep 2018 18:47:32 +0300 Subject: [PATCH 020/812] MAGETWO-91609: Problems with operator more/less in the "catalog Products List" widget - Fixed widget operator less or more --- .../Rule/Model/Condition/Sql/Builder.php | 4 + .../Unit/Model/Condition/Sql/BuilderTest.php | 119 ++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php index 2894de0f19b87..1afe995f837ea 100644 --- a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php +++ b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php @@ -32,9 +32,13 @@ class Builder '==' => ':field = ?', '!=' => ':field <> ?', '>=' => ':field >= ?', + '>e;' => ':field >= ?', '>' => ':field > ?', + '>' => ':field > ?', '<=' => ':field <= ?', + '<e;' => ':field <= ?', '<' => ':field < ?', + '<' => ':field < ?', '{}' => ':field IN (?)', '!{}' => ':field NOT IN (?)', '()' => ':field IN (?)', diff --git a/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php b/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php index daf7b1462c722..b3ddaa51c2605 100644 --- a/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php +++ b/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php @@ -78,4 +78,123 @@ public function testAttachConditionToCollection() $this->_builder->attachConditionToCollection($collection, $combine); } + + /** + * Test for attach condition to collection with operator in html format + * + * @covers \Magento\Rule\Model\Condition\Sql\Builder::attachConditionToCollection() + * @return void; + */ + public function testAttachConditionAsHtmlToCollection() + { + $abstractCondition = $this->getMockForAbstractClass( + \Magento\Rule\Model\Condition\AbstractCondition::class, + [], + '', + false, + false, + true, + ['getOperatorForValidate', 'getMappedSqlField', 'getAttribute', 'getBindArgumentValue'] + ); + + $abstractCondition->expects($this->once()) + ->method('getMappedSqlField') + ->will($this->returnValue('argument')); + + $abstractCondition->expects($this->once()) + ->method('getOperatorForValidate') + ->will($this->returnValue('>')); + + $abstractCondition->expects($this->at(1)) + ->method('getAttribute') + ->will($this->returnValue('attribute')); + + $abstractCondition->expects($this->at(2)) + ->method('getAttribute') + ->will($this->returnValue('attribute')); + + $abstractCondition->expects($this->once()) + ->method('getBindArgumentValue') + ->will($this->returnValue(10)); + + $conditions = [ + $abstractCondition + ]; + + $collection = $this->createPartialMock( + \Magento\Eav\Model\Entity\Collection\AbstractCollection::class, + [ + 'getResource', + 'getSelect', + 'getStoreId', + 'getDefaultStoreId', + ] + ); + + $combine = $this->createPartialMock(\Magento\Rule\Model\Condition\Combine::class, + [ + 'getConditions', + 'getValue', + 'getAggregator' + ] + ); + $resource = $this->createPartialMock(\Magento\Framework\DB\Adapter\Pdo\Mysql::class, ['getConnection']); + $select = $this->createPartialMock(\Magento\Framework\DB\Select::class, ['where']); + $select->expects($this->never()) + ->method('where'); + + $connection = $this->getMockForAbstractClass( + \Magento\Framework\DB\Adapter\AdapterInterface::class, + ['quoteInto'], + '', + false + ); + + $connection->expects($this->once()) + ->method('quoteInto') + ->with(' > ?', 10) + ->will($this->returnValue(' > 10')); + + $collection->expects($this->once()) + ->method('getResource') + ->will($this->returnValue($resource)); + + $collection->expects($this->once()) + ->method('getStoreId') + ->willReturn(1); + + $collection->expects($this->once()) + ->method('getDefaultStoreId') + ->willReturn(1); + + $resource->expects($this->once()) + ->method('getConnection') + ->will($this->returnValue($connection)); + + $combine->expects($this->once()) + ->method('getValue') + ->willReturn('attribute'); + + $combine->expects($this->once()) + ->method('getAggregator') + ->willReturn(' AND '); + + $combine->expects($this->at(0)) + ->method('getConditions') + ->will($this->returnValue($conditions)); + + $combine->expects($this->at(1)) + ->method('getConditions') + ->will($this->returnValue($conditions)); + + $combine->expects($this->at(2)) + ->method('getConditions') + ->will($this->returnValue($conditions)); + + $combine->expects($this->at(3)) + ->method('getConditions') + ->will($this->returnValue($conditions)); + + $this->_builder->attachConditionToCollection($collection, $combine); + } } From 5725c92582a43d15dc58b415e90cb2a1e31ea648 Mon Sep 17 00:00:00 2001 From: vprohorov <prohorov.vital@gmail.com> Date: Wed, 5 Sep 2018 05:00:39 +0300 Subject: [PATCH 021/812] MAGETWO-62728: My Wishlist - quantity input box issue - Adding maxlength to input validation --- .../Wishlist/view/frontend/templates/item/column/cart.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml index 9ea0d1a823235..e124edc6a43e1 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml @@ -21,7 +21,7 @@ $product = $item->getProduct(); <div class="field qty"> <label class="label" for="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]"><span><?= $block->escapeHtml(__('Qty')) ?></span></label> <div class="control"> - <input type="number" data-role="qty" id="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true}" + <input type="number" data-role="qty" id="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true,'maxlength':8}" name="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" value="<?= /* @noEscape */ (int)($block->getAddToCartQty($item) * 1) ?>"> </div> </div> From 335c173deba047e558f44f69f5538f1a5be2b54a Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Wed, 5 Sep 2018 15:13:10 +0200 Subject: [PATCH 022/812] Adjusted complexity limiter for developer mode --- .../Framework/GraphQl/Query/QueryComplexityLimiter.php | 10 ++++++---- .../Magento/Framework/GraphQl/Query/QueryProcessor.php | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index d2d9477e67b1e..a144ef8967f17 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -16,6 +16,8 @@ * Sets limits for query complexity. A single GraphQL query can potentially * generate thousands of database operations so, the very complex queries * should be filtered and rejected. + * + * https://github.com/webonyx/graphql-php/blob/master/docs/security.md#query-complexity-analysis */ class QueryComplexityLimiter { @@ -42,15 +44,15 @@ public function __construct( } /** - * @param bool $disableIntrospection + * @param bool $developerMode */ - public function execute(bool $disableIntrospection = false): void + public function execute(bool $developerMode = false): void { - DocumentValidator::addRule(new QueryDepth($this->queryDepth)); DocumentValidator::addRule(new QueryComplexity($this->queryComplexity)); - if ($disableIntrospection) { + if (!$developerMode) { DocumentValidator::addRule(new DisableIntrospection()); + DocumentValidator::addRule(new QueryDepth($this->queryDepth)); } } } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php index e3a2ea3fa753e..57ff56b665a1e 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php @@ -24,7 +24,7 @@ class QueryProcessor /** * @var QueryComplexityLimiter */ - protected $queryComplexityLimiter; + private $queryComplexityLimiter; /** * @param ExceptionFormatter $exceptionFormatter @@ -55,8 +55,8 @@ public function process( array $variableValues = null, string $operationName = null ) : array { - $disableIntrospection = !$this->exceptionFormatter->shouldShowDetail(); - $this->queryComplexityLimiter->execute($disableIntrospection); + $developerMode = !$this->exceptionFormatter->shouldShowDetail(); + $this->queryComplexityLimiter->execute($developerMode); $rootValue = null; return \GraphQL\GraphQL::executeQuery( From 9d244de1504677845aa7ccbf4a61218f851b790b Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Thu, 6 Sep 2018 10:39:17 +0300 Subject: [PATCH 023/812] MAGETWO-91650: Translation not working for product alerts - Translate email depending on the store on which the notification button was clicked --- app/code/Magento/ProductAlert/Model/Email.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/code/Magento/ProductAlert/Model/Email.php b/app/code/Magento/ProductAlert/Model/Email.php index 7bc4aba351546..d425a0c6b052c 100644 --- a/app/code/Magento/ProductAlert/Model/Email.php +++ b/app/code/Magento/ProductAlert/Model/Email.php @@ -307,11 +307,7 @@ public function send() return false; } - if ($this->_customer->getStoreId() > 0) { - $store = $this->_storeManager->getStore($this->_customer->getStoreId()); - } else { - $store = $this->_website->getDefaultStore(); - } + $store = $this->_website->getDefaultStore(); $storeId = $store->getId(); if ($this->_type == 'price' && !$this->_scopeConfig->getValue( From 0ff4e4ead023aa878823bc6d28aaf74d7851b98d Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Fri, 7 Sep 2018 13:10:46 +0400 Subject: [PATCH 024/812] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Remove test from CE --- .../Mftf/Section/AdminSalesConfigSection.xml | 10 ---- .../CheckingGiftOptionsActionGroup.xml | 8 +-- .../Test/Mftf/Data/GiftOptionsData.xml | 13 +--- .../Test/Mftf/Metadata/gift_options-meta.xml | 31 ---------- .../StoreFrontCheckingGiftOptionsTest.xml | 59 ------------------- .../Mftf/Section/MultishippingSection.xml} | 5 +- ...AdminShipmentAddressInformationSection.xml | 3 +- 7 files changed, 9 insertions(+), 120 deletions(-) delete mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml delete mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml rename app/code/Magento/{Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml => Multishipping/Test/Mftf/Section/MultishippingSection.xml} (51%) diff --git a/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml b/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml index aefb7c5441c5b..95a9f75768c62 100644 --- a/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml +++ b/app/code/Magento/Config/Test/Mftf/Section/AdminSalesConfigSection.xml @@ -10,18 +10,8 @@ <element name="enableMAPUseSystemValue" type="checkbox" selector="#sales_msrp_enabled_inherit"/> <element name="enableMAPSelect" type="select" selector="#sales_msrp_enabled"/> <element name="giftOptions" type="select" selector="#sales_gift_options-head"/> - <element name="allowGiftWrappingOnOrderLevel" type="select" selector="#sales_gift_options_wrapping_allow_order"/> - <element name="levelNo" type="select" selector="//select[@id='sales_gift_options_wrapping_allow_order']//option[text()='No']"/> - <element name="levelYes" type="select" selector="//select[@id='sales_gift_options_wrapping_allow_order']//option[text()='Yes']"/> - <element name="allowGiftWrappingForOrderItems" type="select" selector="#sales_gift_options_wrapping_allow_items"/> - <element name="itemsNo" type="select" selector="//select[@id='sales_gift_options_wrapping_allow_items']//option[text()='No']"/> - <element name="itemsYes" type="select" selector="//select[@id='sales_gift_options_wrapping_allow_items']//option[text()='Yes']"/> <element name="allowGiftReceipt" type="select" selector="#sales_gift_options_allow_gift_receipt"/> - <element name="receiptNo" type="select" selector="//select[@id='sales_gift_options_allow_gift_receipt']//option[text()='No']"/> - <element name="receiptYes" type="select" selector="//select[@id='sales_gift_options_allow_gift_receipt']//option[text()='Yes']"/> <element name="allowPrintedCard" type="select" selector="#sales_gift_options_allow_printed_card"/> - <element name="printedCardNo" type="select" selector="//select[@id='sales_gift_options_allow_printed_card']//option[text()='No']"/> - <element name="printedCardYes" type="select" selector="//select[@id='sales_gift_options_allow_printed_card']//option[text()='Yes']"/> <element name="go" type="select" selector="//a[@id='sales_gift_options-head']/ancestor::div[@class='entry-edit-head admin__collapsible-block']"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml b/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml index 05dad757e287f..f81877006c7a6 100644 --- a/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml +++ b/app/code/Magento/GiftMessage/Test/Mftf/ActionGroup/CheckingGiftOptionsActionGroup.xml @@ -7,11 +7,11 @@ --> <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"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <actionGroup name="CheckingGiftOptionsActionGroup"> - <click stepKey="clickOnCheckoutWithMultipleAddresses" selector="{{StoreFrontShoppingCartSection.checkoutWithMultipleAddresses}}"/> - <waitForPageLoad stepKey="waitForShipToMultipleAddresses"/> - <click stepKey="goToShippingInformation" selector="{{StoreFrontShoppingCartSection.goToShippingInformation}}"/> + <click stepKey="clickOnCheckoutWithMultipleAddresses" selector="{{MultishippingSection.checkoutWithMultipleAddresses}}"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <click stepKey="goToShippingInformation" selector="{{AdminShipmentAddressInformationSection.goToShippingInformation}}"/> <waitForPageLoad stepKey="waitForGiftOption"/> <click stepKey="thickAddGiftOptions" selector="{{GiftOptionsOnFrontSection.giftOptionCheckbox}}"/> <waitForPageLoad stepKey="waitForOptions"/> diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml b/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml index b2bc71b5b7a7b..951bbd3b787b7 100644 --- a/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml +++ b/app/code/Magento/GiftMessage/Test/Mftf/Data/GiftOptionsData.xml @@ -7,15 +7,7 @@ --> <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="ConfigAllowGiftWrappingForOrderItemsOnly" type="gift_options_config_state"> - <requiredEntity type="wrapping_allow_order">wrappingAllowOrder</requiredEntity> - <requiredEntity type="allow_gift_receipt">allowGiftReceipt</requiredEntity> - <requiredEntity type="allow_printed_card">allowPrintedCard</requiredEntity> - </entity> - <entity name="wrappingAllowOrder" type="wrapping_allow_order"> - <data key="value">0</data> - </entity> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <entity name="allowGiftReceipt" type="allow_gift_receipt"> <data key="value">0</data> </entity> @@ -28,9 +20,6 @@ <requiredEntity type="allow_gift_receipt">defaultAllowGiftReceipt</requiredEntity> <requiredEntity type="allow_printed_card">defaultAllowPrintedCard</requiredEntity> </entity> - <entity name="defaultWrappingAllowOrder" type="wrapping_allow_order"> - <data key="value">1</data> - </entity> <entity name="defaultAllowGiftReceipt" type="allow_gift_receipt"> <data key="value">1</data> </entity> diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml b/app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.xml deleted file mode 100644 index a32f5694f2470..0000000000000 --- a/app/code/Magento/GiftMessage/Test/Mftf/Metadata/gift_options-meta.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. - */ ---> - -<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> - <operation name="SalesGiftOptionsConfigState" dataType="gift_options_config_state" type="create" auth="adminFormKey" url="/admin/system_config/save/section/sales/" method="POST"> - <object key="groups" dataType="gift_options_config_state"> - <object key="gift_options" dataType="gift_options_config_state"> - <object key="fields" dataType="gift_options_config_state"> - <object key="wrapping_allow_order" dataType="wrapping_allow_order"> - <field key="value">string</field> - </object> - <object key="wrapping_allow_items" dataType="wrapping_allow_items"> - <field key="value">string</field> - </object> - <object key="allow_gift_receipt" dataType="allow_gift_receipt"> - <field key="value">string</field> - </object> - <object key="allow_printed_card" dataType="allow_printed_card"> - <field key="value">string</field> - </object> - </object> - </object> - </object> - </operation> -</operations> diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml b/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml deleted file mode 100644 index 0bb5bf0e71fa8..0000000000000 --- a/app/code/Magento/GiftMessage/Test/Mftf/Test/StoreFrontCheckingGiftOptionsTest.xml +++ /dev/null @@ -1,59 +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="StoreFrontCheckingGiftOptionsTest"> - <annotations> - <features value="Gift"/> - <stories value="Checking Gift Options on front end order page"/> - <title value="Checking Gift Options on front end order page"/> - <description value="Admin should be able to control gift options"/> - <severity value="MAJOR"/> - <testCaseId value="MAGETWO-94209"/> - <group value="Gift"/> - </annotations> - <before> - <createData stepKey="category" entity="SimpleSubCategory"/> - <createData stepKey="product1" entity="SimpleProduct"> - <requiredEntity createDataKey="category"/> - </createData> - <createData stepKey="product2" entity="SimpleProduct"> - <requiredEntity createDataKey="category"/> - </createData> - <createData entity="Simple_US_Customer" stepKey="customer"/> - <createData entity="ConfigAllowGiftWrappingForOrderItemsOnly" stepKey="configAllowGiftWrappingForOrderItemsOnly"/> - - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount"> - <argument name="Customer" value="$$customer$$"/> - </actionGroup> - - </before> - - <amOnPage url="$$product1.name$$.html" stepKey="goToProduct1"/> - <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProduct1"> - <argument name="productName" value="$$product1.name$$"/> - </actionGroup> - <amOnPage url="$$product2.name$$.html" stepKey="goToProduct2"/> - <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProduct2"> - <argument name="productName" value="$$product2.name$$"/> - </actionGroup> - <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="openCart"/> - <actionGroup ref="CheckingGiftOptionsActionGroup" stepKey="checkGiftOptions"/> - - <after> - <createData entity="DefaultConfigGiftOptions" stepKey="restoreDefaultConfigGiftOptions"/> - <deleteData stepKey="deleteCategory" createDataKey="category"/> - <deleteData stepKey="deleteProduct1" createDataKey="product1"/> - <deleteData stepKey="deleteProduct2" createDataKey="product2"/> - <deleteData stepKey="deleteCustomer" createDataKey="customer"/> - <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> - </after> - </test> -</tests> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml similarity index 51% rename from app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml rename to app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml index 303c5e526423f..e7d57af1172c6 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontShoppingCartSection.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml @@ -7,9 +7,8 @@ --> <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="StoreFrontShoppingCartSection"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <section name="MultishippingSection"> <element name="checkoutWithMultipleAddresses" type="button" selector="//span[text()='Check Out with Multiple Addresses']"/> - <element name="goToShippingInformation" type="button" selector="//button[@title='Go to Shipping Information']"/> </section> </sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml index ea4dde8190bc7..10878310c262f 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml @@ -7,11 +7,12 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <section name="AdminShipmentAddressInformationSection"> <element name="billingAddress" type="text" selector=".order-billing-address address"/> <element name="billingAddressEdit" type="button" selector=".order-billing-address .actions a"/> <element name="shippingAddress" type="text" selector=".order-shipping-address address"/> <element name="shippingAddressEdit" type="button" selector=".order-shipping-address .actions a"/> + <element name="goToShippingInformation" type="button" selector="//button[@title='Go to Shipping Information']"/> </section> </sections> From 10765ab93c5336dbab89c71f80a0fe14db9ca38a Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Fri, 7 Sep 2018 14:35:54 +0300 Subject: [PATCH 025/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fixes after discussion. Added configuration to enable/disable toolbar memorizing. --- .../Block/Product/ProductList/Toolbar.php | 19 ++++---- .../Product/ProductList/ToolbarMemorizer.php | 48 +++++++++++-------- .../Magento/Catalog/etc/adminhtml/system.xml | 6 +++ app/code/Magento/Catalog/etc/config.xml | 1 + 4 files changed, 47 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index 0e971dcb5b9f5..e3ed8ef94b74b 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -274,7 +274,7 @@ public function getCurrentOrder() $order = $defaultOrder; } - if ($order != $defaultOrder) { + if ($order != $defaultOrder && $this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::ORDER_PARAM_NAME, $order, $defaultOrder); } @@ -300,7 +300,7 @@ public function getCurrentDirection() $dir = $this->_direction; } - if ($dir != $this->_direction) { + if ($dir != $this->_direction && $this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::DIRECTION_PARAM_NAME, $dir, $this->_direction); } @@ -442,7 +442,7 @@ public function getCurrentMode() $mode = $defaultMode; } - if ($mode != $defaultMode) { + if ($mode != $defaultMode && $this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::MODE_PARAM_NAME, $mode, $defaultMode); } @@ -602,7 +602,7 @@ public function getLimit() $limit = $defaultLimit; } - if ($limit != $defaultLimit) { + if ($limit != $defaultLimit && $this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::LIMIT_PARAM_NAME, $limit, $defaultLimit); } @@ -711,15 +711,18 @@ public function getPagerHtml() public function getWidgetOptionsJson(array $customOptions = []) { $defaultMode = $this->_productListHelper->getDefaultViewMode($this->getModes()); + $defaultDirection = $this->_direction ?: ProductList::DEFAULT_SORT_DIRECTION; + $isMemorizingAllowed = $this->toolbarMemorizer->isMemorizingAllowed(); $options = [ 'mode' => ToolbarModel::MODE_PARAM_NAME, 'direction' => ToolbarModel::DIRECTION_PARAM_NAME, 'order' => ToolbarModel::ORDER_PARAM_NAME, 'limit' => ToolbarModel::LIMIT_PARAM_NAME, - 'modeDefault' => $defaultMode, - 'directionDefault' => $this->_direction ?: ProductList::DEFAULT_SORT_DIRECTION, - 'orderDefault' => $this->getOrderField(), - 'limitDefault' => $this->_productListHelper->getDefaultLimitPerPageValue($defaultMode), + 'modeDefault' => $isMemorizingAllowed ? false : $defaultMode, + 'directionDefault' => $isMemorizingAllowed ? false : $defaultDirection, + 'orderDefault' => $isMemorizingAllowed ? false : $this->getOrderField(), + 'limitDefault' => $isMemorizingAllowed ? false : + $this->_productListHelper->getDefaultLimitPerPageValue($defaultMode), 'url' => $this->getPagerUrl(), ]; $options = array_replace_recursive($options, $customOptions); diff --git a/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php b/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php index 1ff63a0fa3448..4e65a4f9853e7 100644 --- a/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php +++ b/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php @@ -3,9 +3,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +declare(strict_types=1); + namespace Magento\Catalog\Model\Product\ProductList; use Magento\Catalog\Model\Session as CatalogSession; +use Magento\Framework\App\Config\ScopeConfigInterface; /** * Class ToolbarMemorizer @@ -14,6 +18,11 @@ */ class ToolbarMemorizer { + /** + * XML PATH to enable/disable saving toolbar parameters to session + */ + const XML_PATH_CATALOG_REMEMBER_PAGINATION = 'catalog/frontend/remember_pagination'; + /** * @var CatalogSession */ @@ -25,9 +34,9 @@ class ToolbarMemorizer private $toolbarModel; /** - * @var bool + * @var ScopeConfigInterface */ - private $paramsMemorizeAllowed = true; + private $scopeConfig; /** * @var string|bool @@ -52,13 +61,16 @@ class ToolbarMemorizer /** * @param Toolbar $toolbarModel * @param CatalogSession $catalogSession + * @param ScopeConfigInterface $scopeConfig */ public function __construct( Toolbar $toolbarModel, - CatalogSession $catalogSession + CatalogSession $catalogSession, + ScopeConfigInterface $scopeConfig ) { $this->toolbarModel = $toolbarModel; $this->catalogSession = $catalogSession; + $this->scopeConfig = $scopeConfig; } /** @@ -118,27 +130,28 @@ public function getLimit() } /** - * Disable list state params memorizing + * Method to save all catalog parameters in catalog session * - * @return $this + * @return void */ - public function disableParamsMemorizing() + public function memorizeParams() { - $this->paramsMemorizeAllowed = false; - return $this; + if (!$this->catalogSession->getParamsMemorizeDisabled() && $this->isMemorizingAllowed()) { + $this->memorizeParam(Toolbar::ORDER_PARAM_NAME, $this->getOrder()) + ->memorizeParam(Toolbar::DIRECTION_PARAM_NAME, $this->getDirection()) + ->memorizeParam(Toolbar::MODE_PARAM_NAME, $this->getMode()) + ->memorizeParam(Toolbar::LIMIT_PARAM_NAME, $this->getLimit()); + } } /** - * Method to save all catalog parameters in catalog session + * Check configuration for enabled/disabled toolbar memorizing * - * @return void + * @return bool */ - public function memorizeParams() + public function isMemorizingAllowed() { - $this->memorizeParam(Toolbar::ORDER_PARAM_NAME, $this->getOrder()) - ->memorizeParam(Toolbar::DIRECTION_PARAM_NAME, $this->getDirection()) - ->memorizeParam(Toolbar::MODE_PARAM_NAME, $this->getMode()) - ->memorizeParam(Toolbar::LIMIT_PARAM_NAME, $this->getLimit()); + return $this->scopeConfig->isSetFlag(self::XML_PATH_CATALOG_REMEMBER_PAGINATION); } /** @@ -150,10 +163,7 @@ public function memorizeParams() */ private function memorizeParam($param, $value) { - if ($value && $this->paramsMemorizeAllowed && - !$this->catalogSession->getParamsMemorizeDisabled() && - $this->catalogSession->getData($param) != $value - ) { + if ($value && $this->catalogSession->getData($param) != $value) { $this->catalogSession->setData($param, $value); } return $this; diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml index 71a799fd22427..be35ae2e5549d 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/system.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml @@ -92,6 +92,12 @@ <comment>Whether to show "All" option in the "Show X Per Page" dropdown</comment> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> + <field id="remember_pagination" translate="label comment" type="select" sortOrder="7" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> + <label>Remember Category Pagination</label> + <comment>Note that SEO and performance experience may be negative by this feature enabled. + Also it will increase cache storage consumption.</comment> + <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + </field> </group> <group id="placeholder" translate="label" sortOrder="300" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Product Image Placeholders</label> diff --git a/app/code/Magento/Catalog/etc/config.xml b/app/code/Magento/Catalog/etc/config.xml index 1d92197e390a1..9ede3885f9a78 100644 --- a/app/code/Magento/Catalog/etc/config.xml +++ b/app/code/Magento/Catalog/etc/config.xml @@ -30,6 +30,7 @@ <flat_catalog_category>0</flat_catalog_category> <default_sort_by>position</default_sort_by> <parse_url_directives>1</parse_url_directives> + <remember_pagination>0</remember_pagination> </frontend> <product> <flat> From cd649d162681f3698cb0f989cb624f79ae9f4dfc Mon Sep 17 00:00:00 2001 From: Oleksandr_Hodzevych <Oleksandr_Hodzevych@epam.com> Date: Fri, 7 Sep 2018 15:10:50 +0300 Subject: [PATCH 026/812] MAGETWO-91609: Problems with operator more/less in the "catalog Products List" widget - Fixed widget operator less or more --- app/code/Magento/Rule/Model/Condition/Sql/Builder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php index 1afe995f837ea..01c671f0b0678 100644 --- a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php +++ b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php @@ -32,11 +32,11 @@ class Builder '==' => ':field = ?', '!=' => ':field <> ?', '>=' => ':field >= ?', - '>e;' => ':field >= ?', + '>=' => ':field >= ?', '>' => ':field > ?', '>' => ':field > ?', '<=' => ':field <= ?', - '<e;' => ':field <= ?', + '<=' => ':field <= ?', '<' => ':field < ?', '<' => ':field < ?', '{}' => ':field IN (?)', From 502e415c948db0eaa72ddd1b3dbe57879e0d97f6 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Fri, 7 Sep 2018 17:37:49 +0300 Subject: [PATCH 027/812] MAGETWO-91649: #13513: Magento ignore store-level url_key of child category in URL rewrite process for global scope - Fixed issue with incorrect url path generation for children categories; --- .../CategoryUrlPathAutogeneratorObserver.php | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php index eb54f0427c11a..5c7a8b16a666e 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php @@ -8,6 +8,7 @@ use Magento\Catalog\Model\Category; use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator; use Magento\CatalogUrlRewrite\Service\V1\StoreViewService; +use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Framework\Event\Observer; use Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider; use Magento\Framework\Event\ObserverInterface; @@ -30,19 +31,27 @@ class CategoryUrlPathAutogeneratorObserver implements ObserverInterface */ protected $storeViewService; + /** + * @var CategoryRepositoryInterface + */ + private $categoryRepository; + /** * @param CategoryUrlPathGenerator $categoryUrlPathGenerator * @param ChildrenCategoriesProvider $childrenCategoriesProvider * @param \Magento\CatalogUrlRewrite\Service\V1\StoreViewService $storeViewService + * @param CategoryRepositoryInterface $categoryRepository */ public function __construct( CategoryUrlPathGenerator $categoryUrlPathGenerator, ChildrenCategoriesProvider $childrenCategoriesProvider, - StoreViewService $storeViewService + StoreViewService $storeViewService, + CategoryRepositoryInterface $categoryRepository ) { $this->categoryUrlPathGenerator = $categoryUrlPathGenerator; $this->childrenCategoriesProvider = $childrenCategoriesProvider; $this->storeViewService = $storeViewService; + $this->categoryRepository = $categoryRepository; } /** @@ -77,22 +86,22 @@ public function execute(\Magento\Framework\Event\Observer $observer) */ protected function updateUrlPathForChildren(Category $category) { - $children = $this->childrenCategoriesProvider->getChildren($category, true); - if ($this->isGlobalScope($category->getStoreId())) { - foreach ($children as $child) { + $childrenIds = $this->childrenCategoriesProvider->getChildrenIds($category, true); + foreach ($childrenIds as $childId) { foreach ($category->getStoreIds() as $storeId) { if ($this->storeViewService->doesEntityHaveOverriddenUrlPathForStore( $storeId, - $child->getId(), + $childId, Category::ENTITY )) { - $child->setStoreId($storeId); + $child = $this->categoryRepository->get($childId, $storeId); $this->updateUrlPathForCategory($child); } } } } else { + $children = $this->childrenCategoriesProvider->getChildren($category, true); foreach ($children as $child) { $child->setStoreId($category->getStoreId()); $this->updateUrlPathForCategory($child); From 13fa0d74eb5f5fa980d56cead6729c16177e02bc Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 11 Sep 2018 11:10:13 +0300 Subject: [PATCH 028/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Add plugin to set toolbar parameters to context before controller dispatch --- .../Block/Product/ProductList/Toolbar.php | 8 +- .../Model/App/Action/ContextPlugin.php | 77 +++++++++++++++++++ app/code/Magento/Catalog/etc/frontend/di.xml | 4 + 3 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index e3ed8ef94b74b..073e3f8f6173e 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -274,7 +274,7 @@ public function getCurrentOrder() $order = $defaultOrder; } - if ($order != $defaultOrder && $this->toolbarMemorizer->isMemorizingAllowed()) { + if ($this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::ORDER_PARAM_NAME, $order, $defaultOrder); } @@ -300,7 +300,7 @@ public function getCurrentDirection() $dir = $this->_direction; } - if ($dir != $this->_direction && $this->toolbarMemorizer->isMemorizingAllowed()) { + if ($this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::DIRECTION_PARAM_NAME, $dir, $this->_direction); } @@ -442,7 +442,7 @@ public function getCurrentMode() $mode = $defaultMode; } - if ($mode != $defaultMode && $this->toolbarMemorizer->isMemorizingAllowed()) { + if ($this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::MODE_PARAM_NAME, $mode, $defaultMode); } @@ -602,7 +602,7 @@ public function getLimit() $limit = $defaultLimit; } - if ($limit != $defaultLimit && $this->toolbarMemorizer->isMemorizingAllowed()) { + if ($this->toolbarMemorizer->isMemorizingAllowed()) { $this->httpContext->setValue(ToolbarModel::LIMIT_PARAM_NAME, $limit, $defaultLimit); } diff --git a/app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php b/app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php new file mode 100644 index 0000000000000..c5ed81540e29e --- /dev/null +++ b/app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Catalog\Model\App\Action; + +use Magento\Catalog\Model\Product\ProductList\Toolbar as ToolbarModel; +use Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer; +use Magento\Catalog\Model\Session as CatalogSession; +use Magento\Framework\App\Http\Context as HttpContext; + +/** + * Before dispatch plugin for all frontend controllers to update http context. + */ +class ContextPlugin +{ + /** + * @var ToolbarMemorizer + */ + private $toolbarMemorizer; + + /** + * @var CatalogSession + */ + private $catalogSession; + + /** + * @var HttpContext + */ + private $httpContext; + + /** + * @param ToolbarMemorizer $toolbarMemorizer + * @param CatalogSession $catalogSession + * @param HttpContext $httpContext + */ + public function __construct( + ToolbarMemorizer $toolbarMemorizer, + CatalogSession $catalogSession, + HttpContext $httpContext + ) { + $this->toolbarMemorizer = $toolbarMemorizer; + $this->catalogSession = $catalogSession; + $this->httpContext = $httpContext; + } + + /** + * Update http context with catalog sensitive information. + * + * @return void + */ + public function beforeDispatch() + { + if ($this->toolbarMemorizer->isMemorizingAllowed()) { + $order = $this->catalogSession->getData(ToolbarModel::ORDER_PARAM_NAME); + if ($order) { + $this->httpContext->setValue(ToolbarModel::ORDER_PARAM_NAME, $order, false); + } + $direction = $this->catalogSession->getData(ToolbarModel::DIRECTION_PARAM_NAME); + if ($direction) { + $this->httpContext->setValue(ToolbarModel::DIRECTION_PARAM_NAME, $direction, false); + } + $mode = $this->catalogSession->getData(ToolbarModel::MODE_PARAM_NAME); + if ($mode) { + $this->httpContext->setValue(ToolbarModel::MODE_PARAM_NAME, $mode, false); + } + $limit = $this->catalogSession->getData(ToolbarModel::LIMIT_PARAM_NAME); + if ($limit) { + $this->httpContext->setValue(ToolbarModel::LIMIT_PARAM_NAME, $limit, false); + } + } + } +} diff --git a/app/code/Magento/Catalog/etc/frontend/di.xml b/app/code/Magento/Catalog/etc/frontend/di.xml index 55098037191e8..a1520b66e83dc 100644 --- a/app/code/Magento/Catalog/etc/frontend/di.xml +++ b/app/code/Magento/Catalog/etc/frontend/di.xml @@ -116,4 +116,8 @@ <plugin name="get_catalog_category_product_index_table_name" type="Magento\Catalog\Model\Indexer\Category\Product\Plugin\TableResolver"/> <plugin name="get_catalog_product_price_index_table_name" type="Magento\Catalog\Model\Indexer\Product\Price\Plugin\TableResolver"/> </type> + <type name="Magento\Framework\App\Action\AbstractAction"> + <plugin name="catalog_app_action_dispatch_controller_context_plugin" + type="Magento\Catalog\Model\App\Action\ContextPlugin" /> + </type> </config> From 5746734cc6345d6b265b3efc8d9c839778eb48e9 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Tue, 11 Sep 2018 13:53:04 +0300 Subject: [PATCH 029/812] MAGETWO-91658: Wrong Checkout Totals Sort Order in cart - Fixed issue with incorrect totals sorting on cart page; --- .../view/frontend/layout/checkout_cart_index.xml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/SalesRule/view/frontend/layout/checkout_cart_index.xml b/app/code/Magento/SalesRule/view/frontend/layout/checkout_cart_index.xml index a5d0be503baad..9e86671500c50 100644 --- a/app/code/Magento/SalesRule/view/frontend/layout/checkout_cart_index.xml +++ b/app/code/Magento/SalesRule/view/frontend/layout/checkout_cart_index.xml @@ -13,14 +13,10 @@ <item name="components" xsi:type="array"> <item name="block-totals" xsi:type="array"> <item name="children" xsi:type="array"> - <item name="before_grandtotal" xsi:type="array"> - <item name="children" xsi:type="array"> - <item name="discount" xsi:type="array"> - <item name="component" xsi:type="string">Magento_SalesRule/js/view/cart/totals/discount</item> - <item name="config" xsi:type="array"> - <item name="title" xsi:type="string" translate="true">Discount</item> - </item> - </item> + <item name="discount" xsi:type="array"> + <item name="component" xsi:type="string">Magento_SalesRule/js/view/cart/totals/discount</item> + <item name="config" xsi:type="array"> + <item name="title" xsi:type="string" translate="true">Discount</item> </item> </item> </item> From dc878446ec83d88080c81ad71ef6fc986806f173 Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Tue, 11 Sep 2018 19:41:28 +0400 Subject: [PATCH 030/812] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Add change related to xsd --- .../GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml b/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml index 9856f009197c1..63243030682bf 100644 --- a/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml +++ b/app/code/Magento/GiftMessage/Test/Mftf/Section/GiftOptionsOnFrontSection.xml @@ -5,7 +5,7 @@ * 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"> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="GiftOptionsOnFrontSection"> <element name="giftOptionCheckbox" type="text" selector="//span[text()='Add Gift Options']"/> <element name="addGiftOptionsForIndividualItems" type="text" selector="//dt[@class='order-title individual']"/> From ca7932ba5e813967018a5052a763bbe65c9abd66 Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <karen_mkhitaryan@epam.com> Date: Fri, 7 Sep 2018 12:10:46 +0300 Subject: [PATCH 031/812] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Remove test from CE --- .../Mftf/Section/AdminShipmentAddressInformationSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml index 3268a6f288371..10878310c262f 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentAddressInformationSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <section name="AdminShipmentAddressInformationSection"> <element name="billingAddress" type="text" selector=".order-billing-address address"/> <element name="billingAddressEdit" type="button" selector=".order-billing-address .actions a"/> From 6d068c79b5bb8fcad3a4b18df2a394fb7beb84f6 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 11 Sep 2018 18:11:30 +0300 Subject: [PATCH 032/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Post toolbar parameters when using toolbar saving. --- .../Block/Product/ProductList/Toolbar.php | 29 +++++++++---- .../frontend/web/js/product/list/toolbar.js | 41 ++++++++++++++++--- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index 073e3f8f6173e..9f1514aab9d6f 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -8,6 +8,7 @@ use Magento\Catalog\Helper\Product\ProductList; use Magento\Catalog\Model\Product\ProductList\Toolbar as ToolbarModel; use Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer; +use Magento\Framework\App\ObjectManager; /** * Product list toolbar @@ -132,6 +133,11 @@ class Toolbar extends \Magento\Framework\View\Element\Template */ private $httpContext; + /** + * @var \Magento\Framework\Data\Form\FormKey + */ + private $formKey; + /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Catalog\Model\Session $catalogSession @@ -142,6 +148,7 @@ class Toolbar extends \Magento\Framework\View\Element\Template * @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper * @param ToolbarMemorizer|null $toolbarMemorizer * @param \Magento\Framework\App\Http\Context|null $httpContext + * @param \Magento\Framework\Data\Form\FormKey|null $formKey * @param array $data */ public function __construct( @@ -154,6 +161,7 @@ public function __construct( \Magento\Framework\Data\Helper\PostHelper $postDataHelper, ToolbarMemorizer $toolbarMemorizer = null, \Magento\Framework\App\Http\Context $httpContext = null, + \Magento\Framework\Data\Form\FormKey $formKey = null, array $data = [] ) { $this->_catalogSession = $catalogSession; @@ -162,12 +170,15 @@ public function __construct( $this->urlEncoder = $urlEncoder; $this->_productListHelper = $productListHelper; $this->_postDataHelper = $postDataHelper; - $this->toolbarMemorizer = $toolbarMemorizer ?: \Magento\Framework\App\ObjectManager::getInstance()->get( + $this->toolbarMemorizer = $toolbarMemorizer ?: ObjectManager::getInstance()->get( ToolbarMemorizer::class ); - $this->httpContext = $httpContext ?: \Magento\Framework\App\ObjectManager::getInstance()->get( + $this->httpContext = $httpContext ?: ObjectManager::getInstance()->get( \Magento\Framework\App\Http\Context::class ); + $this->formKey = $formKey ?: ObjectManager::getInstance()->get( + \Magento\Framework\Data\Form\FormKey::class + ); parent::__construct($context, $data); } @@ -711,19 +722,19 @@ public function getPagerHtml() public function getWidgetOptionsJson(array $customOptions = []) { $defaultMode = $this->_productListHelper->getDefaultViewMode($this->getModes()); - $defaultDirection = $this->_direction ?: ProductList::DEFAULT_SORT_DIRECTION; - $isMemorizingAllowed = $this->toolbarMemorizer->isMemorizingAllowed(); $options = [ 'mode' => ToolbarModel::MODE_PARAM_NAME, 'direction' => ToolbarModel::DIRECTION_PARAM_NAME, 'order' => ToolbarModel::ORDER_PARAM_NAME, 'limit' => ToolbarModel::LIMIT_PARAM_NAME, - 'modeDefault' => $isMemorizingAllowed ? false : $defaultMode, - 'directionDefault' => $isMemorizingAllowed ? false : $defaultDirection, - 'orderDefault' => $isMemorizingAllowed ? false : $this->getOrderField(), - 'limitDefault' => $isMemorizingAllowed ? false : - $this->_productListHelper->getDefaultLimitPerPageValue($defaultMode), + 'modeDefault' => $defaultMode, + 'directionDefault' => $this->_direction ?: ProductList::DEFAULT_SORT_DIRECTION, + 'orderDefault' => $this->getOrderField(), + 'limitDefault' => $this->_productListHelper->getDefaultLimitPerPageValue($defaultMode), 'url' => $this->getPagerUrl(), + 'formKey' => $this->formKey->getFormKey(), + 'pageParam' => ToolbarModel::PAGE_PARM_NAME, + 'post' => $this->toolbarMemorizer->isMemorizingAllowed() ? true : false ]; $options = array_replace_recursive($options, $customOptions); return json_encode(['productListToolbarForm' => $options]); diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index 88be03a04e71a..aee8933194ab1 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -27,7 +27,10 @@ define([ directionDefault: 'asc', orderDefault: 'position', limitDefault: '9', - url: '' + url: '', + formKey: '', + pageParam: 'p', + post: false }, /** @inheritdoc */ @@ -99,12 +102,38 @@ define([ } paramData[paramName] = paramValue; - if (paramValue == defaultValue) { //eslint-disable-line eqeqeq - delete paramData[paramName]; - } - paramData = $.param(paramData); + if (this.options.post) { + var form = document.createElement('form'); + + var params = [this.options.mode, this.options.direction, this.options.order, this.options.limit]; + for (var key in paramData) { + if (params.indexOf(key) !== -1) { + var input = document.createElement('input'); + input.name = key; + input.value = paramData[key]; + form.appendChild(input); + delete paramData[key]; + } + } + var formKey = document.createElement('input'); + formKey.name = 'form_key'; + formKey.value = this.options.formKey; + form.appendChild(formKey); + + paramData = $.param(paramData); + baseUrl = baseUrl + (paramData.length ? '?' + paramData : ''); - location.href = baseUrl + (paramData.length ? '?' + paramData : ''); + form.action = baseUrl; + form.method = 'POST'; + document.body.appendChild(form); + form.submit(); + } else { + if (paramValue == defaultValue) { //eslint-disable-line eqeqeq + delete paramData[paramName]; + } + paramData = $.param(paramData); + location.href = baseUrl + (paramData.length ? '?' + paramData : ''); + } } }); From b2b611107a9988f69ea95db1b09dbfbfa3770c12 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 12 Sep 2018 19:20:52 +0300 Subject: [PATCH 033/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fix tests. --- .../Block/Product/ProductList/Toolbar.php | 1 - .../Block/Product/ProductList/ToolbarTest.php | 25 ++++++++++++++----- .../frontend/web/js/product/list/toolbar.js | 1 - 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index 9f1514aab9d6f..3e3f86cd7de01 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -733,7 +733,6 @@ public function getWidgetOptionsJson(array $customOptions = []) 'limitDefault' => $this->_productListHelper->getDefaultLimitPerPageValue($defaultMode), 'url' => $this->getPagerUrl(), 'formKey' => $this->formKey->getFormKey(), - 'pageParam' => ToolbarModel::PAGE_PARM_NAME, 'post' => $this->toolbarMemorizer->isMemorizingAllowed() ? true : false ]; $options = array_replace_recursive($options, $customOptions); diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php index ac963326dbfa1..8282ffa409f9c 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php @@ -18,6 +18,11 @@ class ToolbarTest extends \PHPUnit\Framework\TestCase */ protected $model; + /** + * @var \Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer | \PHPUnit_Framework_MockObject_MockObject + */ + private $memorizer; + /** * @var \Magento\Framework\Url | \PHPUnit_Framework_MockObject_MockObject */ @@ -62,6 +67,13 @@ protected function setUp() 'getLimit', 'getCurrentPage' ]); + $this->memorizer = $this->createPartialMock(\Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer::class, [ + 'getDirection', + 'getOrder', + 'getMode', + 'getLimit', + 'isMemorizingAllowed' + ]); $this->layout = $this->createPartialMock(\Magento\Framework\View\Layout::class, ['getChildName', 'getBlock']); $this->pagerBlock = $this->createPartialMock(\Magento\Theme\Block\Html\Pager::class, [ 'setUseContainer', @@ -116,6 +128,7 @@ protected function setUp() 'context' => $context, 'catalogConfig' => $this->catalogConfig, 'toolbarModel' => $this->model, + 'toolbarMemorizer' => $this->memorizer, 'urlEncoder' => $this->urlEncoder, 'productListHelper' => $this->productListHelper ] @@ -155,7 +168,7 @@ public function testGetPagerEncodedUrl() public function testGetCurrentOrder() { $order = 'price'; - $this->model->expects($this->once()) + $this->memorizer->expects($this->once()) ->method('getOrder') ->will($this->returnValue($order)); $this->catalogConfig->expects($this->once()) @@ -169,7 +182,7 @@ public function testGetCurrentDirection() { $direction = 'desc'; - $this->model->expects($this->once()) + $this->memorizer->expects($this->once()) ->method('getDirection') ->will($this->returnValue($direction)); @@ -183,7 +196,7 @@ public function testGetCurrentMode() $this->productListHelper->expects($this->once()) ->method('getAvailableViewMode') ->will($this->returnValue(['list' => 'List'])); - $this->model->expects($this->once()) + $this->memorizer->expects($this->once()) ->method('getMode') ->will($this->returnValue($mode)); @@ -232,11 +245,11 @@ public function testGetLimit() $mode = 'list'; $limit = 10; - $this->model->expects($this->once()) + $this->memorizer->expects($this->once()) ->method('getMode') ->will($this->returnValue($mode)); - $this->model->expects($this->once()) + $this->memorizer->expects($this->once()) ->method('getLimit') ->will($this->returnValue($limit)); $this->productListHelper->expects($this->once()) @@ -266,7 +279,7 @@ public function testGetPagerHtml() $this->productListHelper->expects($this->exactly(2)) ->method('getAvailableLimit') ->will($this->returnValue([10 => 10, 20 => 20])); - $this->model->expects($this->once()) + $this->memorizer->expects($this->once()) ->method('getLimit') ->will($this->returnValue($limit)); $this->pagerBlock->expects($this->once()) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index aee8933194ab1..7c47f5bd04d5a 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -29,7 +29,6 @@ define([ limitDefault: '9', url: '', formKey: '', - pageParam: 'p', post: false }, From 00cb15e4f59e6a71dd51b08b3553633eebfebeaf Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Fri, 14 Sep 2018 09:14:40 +0300 Subject: [PATCH 034/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fix bug when memorizing getting disabled after we have params in session already. --- .../Product/ProductList/ToolbarMemorizer.php | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php b/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php index 4e65a4f9853e7..9c1a781d594f7 100644 --- a/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php +++ b/app/code/Magento/Catalog/Model/Product/ProductList/ToolbarMemorizer.php @@ -58,6 +58,11 @@ class ToolbarMemorizer */ private $limit; + /** + * @var bool + */ + private $isMemorizingAllowed; + /** * @param Toolbar $toolbarModel * @param CatalogSession $catalogSession @@ -82,7 +87,7 @@ public function getOrder() { if ($this->order === null) { $this->order = $this->toolbarModel->getOrder() ?? - $this->catalogSession->getData(Toolbar::ORDER_PARAM_NAME); + ($this->isMemorizingAllowed() ? $this->catalogSession->getData(Toolbar::ORDER_PARAM_NAME) : null); } return $this->order; } @@ -96,7 +101,7 @@ public function getDirection() { if ($this->direction === null) { $this->direction = $this->toolbarModel->getDirection() ?? - $this->catalogSession->getData(Toolbar::DIRECTION_PARAM_NAME); + ($this->isMemorizingAllowed() ? $this->catalogSession->getData(Toolbar::DIRECTION_PARAM_NAME) : null); } return $this->direction; } @@ -110,7 +115,7 @@ public function getMode() { if ($this->mode === null) { $this->mode = $this->toolbarModel->getMode() ?? - $this->catalogSession->getData(Toolbar::MODE_PARAM_NAME); + ($this->isMemorizingAllowed() ? $this->catalogSession->getData(Toolbar::MODE_PARAM_NAME) : null); } return $this->mode; } @@ -124,7 +129,7 @@ public function getLimit() { if ($this->limit === null) { $this->limit = $this->toolbarModel->getLimit() ?? - $this->catalogSession->getData(Toolbar::LIMIT_PARAM_NAME); + ($this->isMemorizingAllowed() ? $this->catalogSession->getData(Toolbar::LIMIT_PARAM_NAME) : null); } return $this->limit; } @@ -151,7 +156,10 @@ public function memorizeParams() */ public function isMemorizingAllowed() { - return $this->scopeConfig->isSetFlag(self::XML_PATH_CATALOG_REMEMBER_PAGINATION); + if ($this->isMemorizingAllowed === null) { + $this->isMemorizingAllowed = $this->scopeConfig->isSetFlag(self::XML_PATH_CATALOG_REMEMBER_PAGINATION); + } + return $this->isMemorizingAllowed; } /** From 0400e32d120bc8dc5b94818f76209b789ac6623d Mon Sep 17 00:00:00 2001 From: eugene-shab <dev.eugene.shab@gmail.com> Date: Fri, 14 Sep 2018 10:53:07 +0300 Subject: [PATCH 035/812] Added ProductImage reslover to images. --- .../Model/Resolver/Product/ProductImage.php | 97 +++++++++++++++++++ .../CatalogGraphQl/etc/schema.graphqls | 13 ++- 2 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php new file mode 100644 index 0000000000000..2e6133f1e32cd --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.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\Product; + +use Magento\Catalog\Model\Product; +use Magento\Catalog\Helper\ImageFactory as CatalogImageHelperFactory; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\Resolver\Value; +use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Store\Model\StoreManagerInterface; + +/** + * Returns product image. + */ +class ProductImage implements ResolverInterface +{ + /** + * @var CatalogImageHelperFactory + */ + private $catalogImageHelperFactory; + + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @param ValueFactory $valueFactory + * @param CatalogImageHelperFactory $catalogImageHelperFactory, + * @param StoreManagerInterface $storeManager + */ + public function __construct( + ValueFactory $valueFactory, + CatalogImageHelperFactory $catalogImageHelperFactory, + StoreManagerInterface $storeManager + ) + { + $this->valueFactory = $valueFactory; + $this->catalogImageHelperFactory = $catalogImageHelperFactory; + $this->storeManager = $storeManager; + } + + /** + * Get product's image by type. + * + * {@inheritdoc} + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ): Value + { + if (!isset($value['model'])) { + $result = function () { + return null; + }; + return $this->valueFactory->create($result); + } + /** @var Product $product */ + $product = $value['model']; + $imageType = $field->getName(); + + $catalogImageHelper = $this->catalogImageHelperFactory->create(); + + $imageUrl = $catalogImageHelper->init( + $product, + 'product_' . $imageType, + ['type' => $imageType] + )->getUrl(); + + $imageData = [ + 'url' => $imageUrl, + 'path' => $product->getData($imageType) + ]; + + $result = function () use ($imageData) { + return $imageData; + }; + + return $this->valueFactory->create($result); + } +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 9235ec271a3c2..683dfb8de1f26 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -257,9 +257,9 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ meta_title: String @doc(description: "A string that is displayed in the title bar and tab of the browser and in search results lists") meta_keyword: String @doc(description: "A comma-separated list of keywords that are visible only to search engines") meta_description: String @doc(description: "A brief overview of the product for search results listings, maximum 255 characters") - image: String @doc(description: "The relative path to the main image on the product page") - small_image: String @doc(description: "The relative path to the small image, which is used on catalog pages") - thumbnail: String @doc(description: "The relative path to the product's thumbnail image") + image: ProductImage @doc(description: "The relative path to the main image on the product page") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage") + small_image: ProductImage @doc(description: "The relative path to the small image, which is used on catalog pages") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage") + thumbnail: ProductImage @doc(description: "The relative path to the product's thumbnail image") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage") new_from_date: String @doc(description: "The beginning date for new product listings, and determines if the product is featured as a new product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\NewFromTo") new_to_date: String @doc(description: "The end date for new product listings") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\NewFromTo") tier_price: Float @doc(description: "The price when tier pricing is in effect and the items purchased threshold has been reached") @@ -352,6 +352,11 @@ type CustomizableFileValue @doc(description: "CustomizableFileValue defines the image_size_y: Int @doc(description: "The maximum height of an image") } +type ProductImage @doc(description: "Product image information. Contains image relative path and URL") { + url: String + path: String +} + interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CustomizableOptionTypeResolver") @doc(description: "The CustomizableOptionInterface contains basic information about a customizable option. It can be implemented by several types of configurable options.") { title: String @doc(description: "The display name for this option") required: Boolean @doc(description: "Indicates whether the option is required") @@ -548,6 +553,6 @@ type SortField { } type SortFields @doc(description: "SortFields contains a default value for sort fields and all available sort fields") { - default: String @doc(description: "Default value of sort fields") + default: String @doc(description: "Default value of sort fields") options: [SortField] @doc(description: "Available sort fields") } From 277c81fe005884724cfe1298f4f7cdeda3d5901a Mon Sep 17 00:00:00 2001 From: eugene-shab <dev.eugene.shab@gmail.com> Date: Fri, 14 Sep 2018 11:23:03 +0300 Subject: [PATCH 036/812] Updates --- .../Model/Resolver/Product/ProductImage.php | 29 ++++--------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php index 2e6133f1e32cd..811bf08fc1c18 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php @@ -10,14 +10,13 @@ use Magento\Catalog\Model\Product; use Magento\Catalog\Helper\ImageFactory as CatalogImageHelperFactory; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\Value; -use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Store\Model\StoreManagerInterface; /** - * Returns product image. + * Return product image paths by image type. */ class ProductImage implements ResolverInterface { @@ -26,28 +25,20 @@ class ProductImage implements ResolverInterface */ private $catalogImageHelperFactory; - /** - * @var ValueFactory - */ - private $valueFactory; - /** * @var StoreManagerInterface */ private $storeManager; /** - * @param ValueFactory $valueFactory * @param CatalogImageHelperFactory $catalogImageHelperFactory, * @param StoreManagerInterface $storeManager */ public function __construct( - ValueFactory $valueFactory, CatalogImageHelperFactory $catalogImageHelperFactory, StoreManagerInterface $storeManager ) { - $this->valueFactory = $valueFactory; $this->catalogImageHelperFactory = $catalogImageHelperFactory; $this->storeManager = $storeManager; } @@ -63,13 +54,9 @@ public function resolve( ResolveInfo $info, array $value = null, array $args = null - ): Value - { + ) { if (!isset($value['model'])) { - $result = function () { - return null; - }; - return $this->valueFactory->create($result); + throw new GraphQlInputException(__('"model" value should be specified')); } /** @var Product $product */ $product = $value['model']; @@ -88,10 +75,6 @@ public function resolve( 'path' => $product->getData($imageType) ]; - $result = function () use ($imageData) { - return $imageData; - }; - - return $this->valueFactory->create($result); + return $imageData; } -} \ No newline at end of file +} From 819b1178eca59bb530b6cca9fd7a1a7cbde28f4f Mon Sep 17 00:00:00 2001 From: eugene-shab <dev.eugene.shab@gmail.com> Date: Fri, 14 Sep 2018 14:44:34 +0300 Subject: [PATCH 037/812] Update code style. --- .../Model/Resolver/Product/ProductImage.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php index 811bf08fc1c18..3cf961c0f4225 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php @@ -31,14 +31,13 @@ class ProductImage implements ResolverInterface private $storeManager; /** - * @param CatalogImageHelperFactory $catalogImageHelperFactory, - * @param StoreManagerInterface $storeManager + * @param CatalogImageHelperFactory $catalogImageHelperFactory + * @param StoreManagerInterface $storeManager */ public function __construct( CatalogImageHelperFactory $catalogImageHelperFactory, StoreManagerInterface $storeManager - ) - { + ) { $this->catalogImageHelperFactory = $catalogImageHelperFactory; $this->storeManager = $storeManager; } @@ -46,7 +45,7 @@ public function __construct( /** * Get product's image by type. * - * {@inheritdoc} + * @inheritdoc */ public function resolve( Field $field, @@ -62,6 +61,7 @@ public function resolve( $product = $value['model']; $imageType = $field->getName(); + /** @var \Magento\Catalog\Helper\Image $catalogImageHelper */ $catalogImageHelper = $this->catalogImageHelperFactory->create(); $imageUrl = $catalogImageHelper->init( From 6c168dd9ced1f3eb141b01dc8091319b474811a6 Mon Sep 17 00:00:00 2001 From: Bartosz Kubicki <bartosz.kubicki@lizardmedia.pl> Date: Tue, 11 Sep 2018 19:38:22 +0200 Subject: [PATCH 038/812] Adding trimming sku value function to sku backend model. Adding trimming sku value function to sku backend model. Adding frontend validation for sku field. --- .../Model/Product/Attribute/Backend/Sku.php | 14 ++++++++++++++ .../DataProvider/Product/Form/Modifier/General.php | 3 ++- app/code/Magento/Ui/i18n/en_US.csv | 1 + .../Ui/view/base/web/js/lib/validation/rules.js | 6 ++++++ lib/web/i18n/en_US.csv | 1 + lib/web/mage/validation.js | 6 ++++++ 6 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php index a652d0ef90213..2ea3b9aaf10a8 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php @@ -97,6 +97,7 @@ protected function _generateUniqueSku($object) public function beforeSave($object) { $this->_generateUniqueSku($object); + $this->trimValue($object); return parent::beforeSave($object); } @@ -127,4 +128,17 @@ protected function _getLastSimilarAttributeValueIncrement($attribute, $object) $data = $connection->fetchOne($select, $bind); return abs((int)str_replace($value, '', $data)); } + + /** + * @param Product $object + * @return void + */ + private function trimValue($object) + { + $attrCode = $this->getAttribute()->getAttributeCode(); + $value = $object->getData($attrCode); + if ($value) { + $object->setData($attrCode, trim($value)); + } + } } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php index 98de8ea347671..e0b0d066c1c1d 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php @@ -361,7 +361,8 @@ protected function customizeNameListeners(array $meta) $skuPath . static::META_CONFIG_PATH, $meta, [ - 'autoImportIfEmpty' => true + 'autoImportIfEmpty' => true, + 'validation' => ['no-marginal-whitespace' => true] ] ); diff --git a/app/code/Magento/Ui/i18n/en_US.csv b/app/code/Magento/Ui/i18n/en_US.csv index 106526f66e708..2731d4be182a4 100644 --- a/app/code/Magento/Ui/i18n/en_US.csv +++ b/app/code/Magento/Ui/i18n/en_US.csv @@ -58,6 +58,7 @@ Keyword,Keyword "Letters, numbers, spaces or underscores only please","Letters, numbers, spaces or underscores only please" "Letters only please","Letters only please" "No white space please","No white space please" +"No marginal white space please","No marginal white space please" "Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx","Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx" "A positive or negative non-decimal number please","A positive or negative non-decimal number please" "The specified vehicle identification number (VIN) is invalid.","The specified vehicle identification number (VIN) is invalid." diff --git a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js index 1103f3e54a4cf..ced16e01b2bc4 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js @@ -116,6 +116,12 @@ define([ }, $.mage.__('No white space please') ], + 'no-marginal-whitespace': [ + function (value) { + return !/^\s+|\s+$/i.test(value); + }, + $.mage.__('No marginal white space please') + ], 'zip-range': [ function (value) { return /^90[2-5]-\d{2}-\d{4}$/.test(value); diff --git a/lib/web/i18n/en_US.csv b/lib/web/i18n/en_US.csv index 5c63a191420a4..bca42473e2f0b 100644 --- a/lib/web/i18n/en_US.csv +++ b/lib/web/i18n/en_US.csv @@ -27,6 +27,7 @@ Submit,Submit "Letters, numbers, spaces or underscores only please","Letters, numbers, spaces or underscores only please" "Letters only please","Letters only please" "No white space please","No white space please" +"No marginal white space please","No marginal white space please" "Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx","Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx" "A positive or negative non-decimal number please","A positive or negative non-decimal number please" "The specified vehicle identification number (VIN) is invalid.","The specified vehicle identification number (VIN) is invalid." diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index d08819ebe94aa..dcfe9c41d311f 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -253,6 +253,12 @@ }, $.mage.__('No white space please') ], + 'no-marginal-whitespace': [ + function (value, element) { + return this.optional(element) || !/^\s+|\s+$/i.test(value); + }, + $.mage.__('No marginal white space please') + ], 'zip-range': [ function (value, element) { return this.optional(element) || /^90[2-5]-\d{2}-\d{4}$/.test(value); From ae42612217947d75aa09b300a34e23487b8954c3 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Sun, 16 Sep 2018 13:58:19 -0300 Subject: [PATCH 039/812] Fix date format for different locales --- .../Magento/Framework/Stdlib/DateTime/Timezone.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 3c2f20fcc186f..242c551c984f9 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -309,11 +309,23 @@ public function formatDateTime( */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') { + $formatter = new \IntlDateFormatter( + $this->_localeResolver->getLocale(), + \IntlDateFormatter::MEDIUM, + \IntlDateFormatter::MEDIUM, + $this->getConfigTimezone(), + null, + null + ); + $unixTime = $formatter->parse($date); + $dateTime = new DateTime($this); + if (!($date instanceof \DateTimeInterface)) { if ($date instanceof \DateTimeImmutable) { $date = new \DateTime($date->format('Y-m-d H:i:s'), new \DateTimeZone($this->getConfigTimezone())); } else { - $date = new \DateTime($date, new \DateTimeZone($this->getConfigTimezone())); + $dateUniversal = $dateTime->gmtDate(null, $unixTime); + $date = new \DateTime($dateUniversal, new \DateTimeZone($this->getConfigTimezone())); } } else { if ($date->getTimezone()->getName() !== $this->getConfigTimezone()) { From 7b728b19841eedc9c53bd6e65dd58c521e2ed56d Mon Sep 17 00:00:00 2001 From: Leandro Rosa <dev.leandrorosa@gmail.com> Date: Sun, 16 Sep 2018 14:30:56 -0300 Subject: [PATCH 040/812] Add checkout_cart_product_add_before event #17830 --- app/code/Magento/Checkout/Model/Cart.php | 4 ++++ .../Checkout/Test/Unit/Model/CartTest.php | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Model/Cart.php b/app/code/Magento/Checkout/Model/Cart.php index be5692a894865..33f4fc9000c21 100644 --- a/app/code/Magento/Checkout/Model/Cart.php +++ b/app/code/Magento/Checkout/Model/Cart.php @@ -370,6 +370,10 @@ public function addProduct($productInfo, $requestInfo = null) if ($productId) { try { + $this->_eventManager->dispatch( + 'checkout_cart_product_add_before', + ['info' => $requestInfo, 'product' => $product] + ); $result = $this->getQuote()->addProduct($product, $request); } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->_checkoutSession->setUseNotice(false); diff --git a/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php b/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php index 40de71e28c05e..88bc57b2c279a 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php @@ -315,6 +315,12 @@ public function testAddProduct($productInfo, $requestInfo) $this->productRepository->expects($this->any()) ->method('getById') ->will($this->returnValue($product)); + + $this->eventManagerMock->expects($this->at(0))->method('dispatch')->with( + 'checkout_cart_product_add_before', + ['info' => $requestInfo, 'product' => $product] + ); + $this->quoteMock->expects($this->once()) ->method('addProduct') ->will($this->returnValue(1)); @@ -322,7 +328,7 @@ public function testAddProduct($productInfo, $requestInfo) ->method('getQuote') ->will($this->returnValue($this->quoteMock)); - $this->eventManagerMock->expects($this->at(0))->method('dispatch')->with( + $this->eventManagerMock->expects($this->at(1))->method('dispatch')->with( 'checkout_cart_product_add_after', ['quote_item' => 1, 'product' => $product] ); @@ -360,6 +366,12 @@ public function testAddProductException() $this->productRepository->expects($this->any()) ->method('getById') ->will($this->returnValue($product)); + + $this->eventManagerMock->expects($this->at(0))->method('dispatch')->with( + 'checkout_cart_product_add_before', + ['info' => 4, 'product' => $product] + ); + $this->quoteMock->expects($this->once()) ->method('addProduct') ->will($this->returnValue('error')); @@ -396,6 +408,11 @@ public function testAddProductExceptionBadParams() ->method('getById') ->will($this->returnValue($product)); + $this->eventManagerMock->expects($this->never())->method('dispatch')->with( + 'checkout_cart_product_add_before', + ['info' => 'bad', 'product' => $product] + ); + $this->eventManagerMock->expects($this->never())->method('dispatch')->with( 'checkout_cart_product_add_after', ['quote_item' => 1, 'product' => $product] From c4fa85bb59e9006f12fa79854da78af4e3fd601e Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Sun, 16 Sep 2018 14:49:06 -0300 Subject: [PATCH 041/812] Move formatter into string conversion block --- app/code/Magento/Newsletter/Model/Queue.php | 3 ++- .../Framework/Stdlib/DateTime/Timezone.php | 22 +++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/Queue.php b/app/code/Magento/Newsletter/Model/Queue.php index efb68fd4243d1..83c80e1e5afce 100644 --- a/app/code/Magento/Newsletter/Model/Queue.php +++ b/app/code/Magento/Newsletter/Model/Queue.php @@ -196,7 +196,8 @@ public function setQueueStartAtByString($startAt) if ($startAt === null || $startAt == '') { $this->setQueueStartAt(null); } else { - $this->setQueueStartAt($this->timezone->convertConfigTimeToUtc($startAt)); + $startAt = $this->timezone->convertConfigTimeToUtc($startAt, null); + $this->setQueueStartAt($startAt); } return $this; } diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 242c551c984f9..54e6e9e1d3caf 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -309,21 +309,21 @@ public function formatDateTime( */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') { - $formatter = new \IntlDateFormatter( - $this->_localeResolver->getLocale(), - \IntlDateFormatter::MEDIUM, - \IntlDateFormatter::MEDIUM, - $this->getConfigTimezone(), - null, - null - ); - $unixTime = $formatter->parse($date); - $dateTime = new DateTime($this); - if (!($date instanceof \DateTimeInterface)) { if ($date instanceof \DateTimeImmutable) { $date = new \DateTime($date->format('Y-m-d H:i:s'), new \DateTimeZone($this->getConfigTimezone())); } else { + $formatter = new \IntlDateFormatter( + $this->_localeResolver->getLocale(), + \IntlDateFormatter::MEDIUM, + \IntlDateFormatter::MEDIUM, + $this->getConfigTimezone(), + null, + $format + ); + $unixTime = $formatter->parse($date); + $dateTime = new DateTime($this); + $dateUniversal = $dateTime->gmtDate(null, $unixTime); $date = new \DateTime($dateUniversal, new \DateTimeZone($this->getConfigTimezone())); } From 6bda779e40699ae1e4b16920374cfd398dea28a8 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Sun, 16 Sep 2018 15:21:20 -0300 Subject: [PATCH 042/812] Convert internationalized date into DateTime object --- app/code/Magento/Newsletter/Model/Queue.php | 2 +- .../Framework/Stdlib/DateTime/Timezone.php | 20 ++++++++++++++++++- .../Stdlib/DateTime/TimezoneInterface.php | 9 +++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/Queue.php b/app/code/Magento/Newsletter/Model/Queue.php index 83c80e1e5afce..67f8cadbfaed4 100644 --- a/app/code/Magento/Newsletter/Model/Queue.php +++ b/app/code/Magento/Newsletter/Model/Queue.php @@ -196,7 +196,7 @@ public function setQueueStartAtByString($startAt) if ($startAt === null || $startAt == '') { $this->setQueueStartAt(null); } else { - $startAt = $this->timezone->convertConfigTimeToUtc($startAt, null); + $startAt = $this->timezone->convertConfigTimeToUtcWithPattern($startAt, 'Y-m-d H:i:s', null); $this->setQueueStartAt($startAt); } return $this; diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 54e6e9e1d3caf..a083b7c6fa986 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -306,8 +306,25 @@ public function formatDateTime( * @param string $format * @throws LocalizedException * @return string + * @deprecated */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') + { + return $this->convertConfigTimeToUtcWithPattern($date, $format); + } + + /** + * Convert date from config timezone to Utc. + * If pass \DateTime object as argument be sure that timezone is the same with config timezone + * + * @param string|\DateTimeInterface $date + * @param string $format + * @param string $pattern + * @throws LocalizedException + * @return string + * @deprecated + */ + public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = 'Y-M-dd HH:mm:ss') { if (!($date instanceof \DateTimeInterface)) { if ($date instanceof \DateTimeImmutable) { @@ -319,7 +336,7 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') \IntlDateFormatter::MEDIUM, $this->getConfigTimezone(), null, - $format + $pattern ); $unixTime = $formatter->parse($date); $dateTime = new DateTime($this); @@ -343,6 +360,7 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') return $date->format($format); } + /** * Retrieve date with time * diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index a8b3fb1a81ffe..5a4b15d6cca0c 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -143,6 +143,15 @@ public function formatDateTime( * @param string $format * @return string * @since 100.1.0 + * @deprecated */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s'); + + /** + * @param $date + * @param string $format + * @param string $pattern + * @return mixed + */ + public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = 'Y-m-d H:i:s'); } From a4f80a9d93c455328a08718b1c7319fde0dfc32f Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Sun, 16 Sep 2018 15:50:33 -0300 Subject: [PATCH 043/812] Force pattern if locale not found --- .../Framework/Stdlib/DateTime/Timezone.php | 8 +++-- .../Test/Unit/DateTime/TimezoneTest.php | 29 +++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index a083b7c6fa986..59b299d176bd1 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -324,14 +324,18 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') * @return string * @deprecated */ - public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = 'Y-M-dd HH:mm:ss') + public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = null) { if (!($date instanceof \DateTimeInterface)) { if ($date instanceof \DateTimeImmutable) { $date = new \DateTime($date->format('Y-m-d H:i:s'), new \DateTimeZone($this->getConfigTimezone())); } else { + $locale = $this->_localeResolver->getLocale(); + if ($locale === null) { + $pattern = 'Y-M-dd HH:mm:ss'; + } $formatter = new \IntlDateFormatter( - $this->_localeResolver->getLocale(), + $locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::MEDIUM, $this->getConfigTimezone(), diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php index d57525590b9e8..ea761db902674 100644 --- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php +++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php @@ -124,11 +124,15 @@ public function dateIncludeTimeDataProvider() * @param string $expectedResult * @dataProvider getConvertConfigTimeToUtcFixtures */ - public function testConvertConfigTimeToUtc($date, $configuredTimezone, $expectedResult) + public function testConvertConfigTimeToUtc($date, $configuredTimezone, $configuredLocale, $expectedResult) { + $this->localeResolver + ->method('getLocale') + ->willReturn($configuredLocale); + $this->scopeConfigWillReturnConfiguredTimezone($configuredTimezone); - $this->assertEquals($expectedResult, $this->getTimezone()->convertConfigTimeToUtc($date)); + $this->assertEquals($expectedResult, $this->getTimezone()->convertConfigTimeToUtcWithPattern($date)); } /** @@ -141,16 +145,37 @@ public function getConvertConfigTimeToUtcFixtures() 'string' => [ '2016-10-10 10:00:00', 'UTC', + null, '2016-10-10 10:00:00' ], + 'string-en_US' => [ + 'Sep 29, 2018, 6:07:38 PM', + 'UTC', + 'en_US', + '2018-09-29 18:07:38' + ], + 'string-pt_BR' => [ + '29 de set de 2018 18:07:38', + 'UTC', + 'pt_BR', + '2018-09-29 18:07:38' + ], + 'string-tr_TR' => [ + '29 Eyl 2018 18:07:38', + 'UTC', + 'tr_TR', + '2018-09-29 18:07:38' + ], 'datetime' => [ new \DateTime('2016-10-10 10:00:00', new \DateTimeZone('UTC')), 'UTC', + null, '2016-10-10 10:00:00' ], 'datetimeimmutable' => [ new \DateTimeImmutable('2016-10-10 10:00:00', new \DateTimeZone('UTC')), 'UTC', + null, '2016-10-10 10:00:00' ] ]; From a44eb5dd5fd2a95f79b617a480b9221704495887 Mon Sep 17 00:00:00 2001 From: lucascalazans <calazans95@hotmail.com> Date: Sun, 16 Sep 2018 17:14:58 -0300 Subject: [PATCH 044/812] #17744 Adding logic to get default billing address --- .../web/js/model/checkout-data-resolver.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 73f4df567903c..6586f647e2404 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -219,15 +219,26 @@ define([ */ applyBillingAddress: function () { var shippingAddress; + var isBillingAddressInitialized; if (quote.billingAddress()) { selectBillingAddress(quote.billingAddress()); return; } - shippingAddress = quote.shippingAddress(); + shippingAddress = quote.billingAddress(); + if(quote.isVirtual()) { + isBillingAddressInitialized = addressList.some(function (addrs) { + if (addrs.isDefaultBilling()) { + selectBillingAddress(addrs); + return true; + } + return false; + }); + } - if (shippingAddress && + if (!isBillingAddressInitialized && + shippingAddress && shippingAddress.canUseForBilling() && (shippingAddress.isDefaultShipping() || !quote.isVirtual()) ) { From 8aedb958f43bf714c934b677c90d4b74b9d1922b Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Sun, 16 Sep 2018 20:24:39 +0000 Subject: [PATCH 045/812] GraphQl-44: prototype of format strategy Signed-off-by: vitaliyboyko <v.boyko@atwix.com> --- ...ibute.php => ProductTextareaAttribute.php} | 25 ++++++---- .../FormatFactory.php | 43 +++++++++++++++++ .../FormatInterface.php | 23 +++++++++ .../Product/ProductTextareaAttribute/Html.php | 47 +++++++++++++++++++ .../CatalogGraphQl/etc/schema.graphqls | 41 +++++++++------- 5 files changed, 152 insertions(+), 27 deletions(-) rename app/code/Magento/CatalogGraphQl/Model/Resolver/Product/{ProductHtmlAttribute.php => ProductTextareaAttribute.php} (67%) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatFactory.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatInterface.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/Html.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductHtmlAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute.php similarity index 67% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductHtmlAttribute.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute.php index 18d15088e6656..f04609f91c86d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductHtmlAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute.php @@ -8,38 +8,40 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Catalog\Model\Product; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\FormatFactory; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Catalog\Helper\Output as OutputHelper; /** * Resolve rendered content for attributes where HTML content is allowed */ -class ProductHtmlAttribute implements ResolverInterface +class ProductTextareaAttribute implements ResolverInterface { + const DEFAULT_CONTENT_FORMAT_IDENTIFIER = 'html'; + /** * @var ValueFactory */ private $valueFactory; /** - * @var OutputHelper + * @var FormatFactory */ - private $outputHelper; + private $formatFactory; /** * @param ValueFactory $valueFactory - * @param OutputHelper $outputHelper + * @param FormatFactory $formatFactory */ public function __construct( ValueFactory $valueFactory, - OutputHelper $outputHelper + FormatFactory $formatFactory ) { $this->valueFactory = $valueFactory; - $this->outputHelper = $outputHelper; + $this->formatFactory = $formatFactory; } /** @@ -62,9 +64,12 @@ public function resolve( /* @var $product Product */ $product = $value['model']; $fieldName = $field->getName(); - $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - $result = function () use ($renderedValue) { - return $renderedValue; + $formatIdentifier = $args['format'] ?? self::DEFAULT_CONTENT_FORMAT_IDENTIFIER; + $format = $this->formatFactory->create($formatIdentifier); + $attribute = ['content' => $format->getContent($product, $fieldName)]; + + $result = function () use ($attribute) { + return $attribute; }; return $this->valueFactory->create($result); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatFactory.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatFactory.php new file mode 100644 index 0000000000000..2aab2d5816083 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatFactory.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute; + +use Magento\Framework\ObjectManagerInterface; + +class FormatFactory +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @param ObjectManagerInterface $objectManager + */ + public function __construct(ObjectManagerInterface $objectManager) + { + $this->objectManager = $objectManager; + } + + /** + * @param string $formatIdentifier + * @param array $data + * @return FormatInterface + */ + public function create(string $formatIdentifier, $data = []) : FormatInterface + { + $formatClassName = 'Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\\' . ucfirst($formatIdentifier); + $formatInstance = $this->objectManager->create($formatClassName, $data); + if (false == $formatInstance instanceof FormatInterface) { + throw new \InvalidArgumentException( + $formatInstance . ' is not instance of \Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\FormatInterface' + ); + } + return $formatInstance; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatInterface.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatInterface.php new file mode 100644 index 0000000000000..fae685b75c060 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/FormatInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute; + +use Magento\Catalog\Model\Product as ModelProduct; + +interface FormatInterface +{ + /** + * @param ModelProduct $product + * @param string $fieldName + * @return string + */ + public function getContent( + ModelProduct $product, + string $fieldName + ): string; +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/Html.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/Html.php new file mode 100644 index 0000000000000..8201c40427dc9 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextareaAttribute/Html.php @@ -0,0 +1,47 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute; + +use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; +use Magento\Catalog\Helper\Output as OutputHelper; +use Magento\Catalog\Model\Product as ModelProduct; + +class Html implements FormatInterface +{ + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @var OutputHelper + */ + private $outputHelper; + + /** + * @param ValueFactory $valueFactory + * @param OutputHelper $outputHelper + */ + public function __construct( + ValueFactory $valueFactory, + OutputHelper $outputHelper + ) { + $this->valueFactory = $valueFactory; + $this->outputHelper = $outputHelper; + } + + /** + * @inheritdoc + */ + public function getContent( + ModelProduct $product, + string $fieldName + ): string { + return $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); + } +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index f63c1a96762c2..82bc262ecf3c3 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -3,16 +3,16 @@ type Query { products ( - search: String @doc(description: "Performs a full-text search using the specified key words."), - filter: ProductFilterInput @doc(description: "Identifies which product attributes to search for and return."), - pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), - currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), - sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") - ): Products - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") + search: String @doc(description: "Performs a full-text search using the specified key words."), + filter: ProductFilterInput @doc(description: "Identifies which product attributes to search for and return."), + pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), + currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), + sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") +): Products + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") category ( - id: Int @doc(description: "Id of the category") - ): CategoryTree + id: Int @doc(description: "Id of the category") +): CategoryTree @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") } @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: String @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductHtmlAttribute") - short_description: String @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductHtmlAttribute") + description: ProductTextareaAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: ProductTextareaAttribute @doc(description: "A short description of the product. Its use depends on the theme.") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -377,10 +377,10 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model product_count: Int @doc(description: "The number of products in the category") default_sort_by: String @doc(description: "The attribute to use for sorting") products( - pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), - currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), - sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") - ): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") + pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), + currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), + sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") +): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") breadcrumbs: [Breadcrumb] @doc(description: "Breadcrumbs, parent categories info") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Breadcrumbs") } @@ -408,8 +408,8 @@ type VirtualProduct implements ProductInterface, CustomizableProductInterface @d } type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface @doc(description: "A simple product is tangible and are usually sold as single units or in fixed quantities") -{ -} + { + } type Products @doc(description: "The Products object is the top-level object returned in a product search") { items: [ProductInterface] @doc(description: "An array of products that match the specified search criteria") @@ -551,3 +551,10 @@ type SortFields @doc(description: "SortFields contains a default value for sort default: String @doc(description: "Default value of sort fields") options: [SortField] @doc(description: "Available sort fields") } + +type ProductTextareaAttribute { + content ( + format: String! @doc(description: "The format of content") +): String + @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextareaAttribute") +} From cde04fc296154d8ade7c390b3eb3def76dcc4c02 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Sun, 16 Sep 2018 20:38:50 +0000 Subject: [PATCH 046/812] GraphQl-45: pretified schema Signed-off-by: vitaliyboyko <v.boyko@atwix.com> --- .../CatalogGraphQl/etc/schema.graphqls | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 82bc262ecf3c3..a9c4a1b4bd8ae 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -3,16 +3,16 @@ type Query { products ( - search: String @doc(description: "Performs a full-text search using the specified key words."), - filter: ProductFilterInput @doc(description: "Identifies which product attributes to search for and return."), - pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), - currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), - sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") -): Products - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") + search: String @doc(description: "Performs a full-text search using the specified key words."), + filter: ProductFilterInput @doc(description: "Identifies which product attributes to search for and return."), + pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), + currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), + sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") + ): Products + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes") category ( - id: Int @doc(description: "Id of the category") -): CategoryTree + id: Int @doc(description: "Id of the category") + ): CategoryTree @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") } @@ -377,10 +377,10 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model product_count: Int @doc(description: "The number of products in the category") default_sort_by: String @doc(description: "The attribute to use for sorting") products( - pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), - currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), - sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") -): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") + pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), + currentPage: Int = 1 @doc(description: "Specifies which page of results to return. The default value is 1."), + sort: ProductSortInput @doc(description: "Specifies which attribute to sort on, and whether to return the results in ascending or descending order.") + ): CategoryProducts @doc(description: "The list of products assigned to the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Products") breadcrumbs: [Breadcrumb] @doc(description: "Breadcrumbs, parent categories info") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\Breadcrumbs") } @@ -408,8 +408,8 @@ type VirtualProduct implements ProductInterface, CustomizableProductInterface @d } type SimpleProduct implements ProductInterface, PhysicalProductInterface, CustomizableProductInterface @doc(description: "A simple product is tangible and are usually sold as single units or in fixed quantities") - { - } +{ +} type Products @doc(description: "The Products object is the top-level object returned in a product search") { items: [ProductInterface] @doc(description: "An array of products that match the specified search criteria") From b1227fc73a76c8dfe7c0af3241b4eeb19e7eb18b Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 17 Sep 2018 15:18:36 +0200 Subject: [PATCH 047/812] Changed query depth limiter behavior --- app/code/Magento/GraphQl/etc/di.xml | 2 +- .../Framework/QueryComplexityLimiterTest.php | 6 +++++- .../GraphQl/Query/QueryComplexityLimiter.php | 14 ++++---------- .../Framework/GraphQl/Query/QueryProcessor.php | 6 ++++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 529280b7cbb6e..b1d24ce6c4a55 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -99,7 +99,7 @@ </type> <type name="Magento\Framework\GraphQl\Query\QueryComplexityLimiter"> <arguments> - <argument name="queryDepth" xsi:type="number">10</argument> + <argument name="queryDepth" xsi:type="number">15</argument> <argument name="queryComplexity" xsi:type="number">50</argument> </arguments> </type> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php index c5f645a94472a..4616c450786ed 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php @@ -9,6 +9,10 @@ use Magento\TestFramework\TestCase\GraphQlAbstract; +/** + * Tests query complexity limiter and depth limiter. + * Actual for production mode only + */ class QueryComplexityLimiterTest extends GraphQlAbstract { /** @@ -159,7 +163,7 @@ public function testQueryDepthIsLimited() } } QUERY; - self::expectExceptionMessageRegExp('/Max query depth should be 10 but got 20/'); + self::expectExceptionMessageRegExp('/Max query depth should be 15 but got 20/'); $this->graphQlQuery($query); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index a144ef8967f17..15e0edb2400ec 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -36,23 +36,17 @@ class QueryComplexityLimiter * @param int $queryComplexity */ public function __construct( - int $queryDepth = 10, + int $queryDepth = 15, int $queryComplexity = 50 ) { $this->queryDepth = $queryDepth; $this->queryComplexity = $queryComplexity; } - /** - * @param bool $developerMode - */ - public function execute(bool $developerMode = false): void + public function execute(): void { DocumentValidator::addRule(new QueryComplexity($this->queryComplexity)); - - if (!$developerMode) { - DocumentValidator::addRule(new DisableIntrospection()); - DocumentValidator::addRule(new QueryDepth($this->queryDepth)); - } + DocumentValidator::addRule(new DisableIntrospection()); + DocumentValidator::addRule(new QueryDepth($this->queryDepth)); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php index 57ff56b665a1e..98e6c840ba682 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php @@ -55,8 +55,10 @@ public function process( array $variableValues = null, string $operationName = null ) : array { - $developerMode = !$this->exceptionFormatter->shouldShowDetail(); - $this->queryComplexityLimiter->execute($developerMode); + var_dump($this->exceptionFormatter->shouldShowDetail()); + if (!$this->exceptionFormatter->shouldShowDetail()) { + $this->queryComplexityLimiter->execute(); + } $rootValue = null; return \GraphQL\GraphQL::executeQuery( From 57fe7c19716fbc248fb7679063f2c4cd6281b7e6 Mon Sep 17 00:00:00 2001 From: "Hakobyan, Lusine" <Lusine_Hakobyan@epam.com> Date: Mon, 17 Sep 2018 17:24:41 +0400 Subject: [PATCH 048/812] MAGETWO-91704: Can't cancel/change payment method after chosen Store Credit - Add locator for automated test --- .../Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml index e4d329bc85057..8aaf626edab33 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml @@ -9,9 +9,10 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminOrderFormPaymentSection"> + <element name="useCustomerBalance" type="checkbox" selector="#p_method_use_customerbalance"/> <element name="header" type="text" selector="#order-methods span.title"/> <element name="getShippingMethods" type="text" selector="#order-shipping_method a.action-default" timeout="30"/> <element name="flatRateOption" type="radio" selector="#s_method_flatrate_flatrate" timeout="30"/> <element name="shippingError" type="text" selector="#order[has_shipping]-error"/> </section> -</sections> \ No newline at end of file +</sections> From 0890139741aa73a06f81223e0793c0994e171f4d Mon Sep 17 00:00:00 2001 From: lucascalazans <calazans95@hotmail.com> Date: Mon, 17 Sep 2018 11:05:54 -0300 Subject: [PATCH 049/812] #17744 Reorganizing code --- .../view/frontend/web/js/model/checkout-data-resolver.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 6586f647e2404..7a1ba9513ec42 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -226,7 +226,7 @@ define([ return; } - shippingAddress = quote.billingAddress(); + if(quote.isVirtual()) { isBillingAddressInitialized = addressList.some(function (addrs) { if (addrs.isDefaultBilling()) { @@ -237,6 +237,7 @@ define([ }); } + shippingAddress = quote.shippingAddress(); if (!isBillingAddressInitialized && shippingAddress && shippingAddress.canUseForBilling() && From b91f5c81dc994d070aca3e7bb453f08cdc8eb756 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 17 Sep 2018 20:29:49 +0300 Subject: [PATCH 050/812] GraphQL-133: Complexity limiter prototype --- .../Framework/GraphQl/Query/QueryComplexityLimiter.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index 15e0edb2400ec..b302f4272527a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -13,6 +13,8 @@ use GraphQL\Validator\Rules\QueryComplexity; /** + * QueryComplexityLimiter + * * Sets limits for query complexity. A single GraphQL query can potentially * generate thousands of database operations so, the very complex queries * should be filtered and rejected. @@ -43,6 +45,11 @@ public function __construct( $this->queryComplexity = $queryComplexity; } + /** + * Sets limits for query complexity + * + * @return void + */ public function execute(): void { DocumentValidator::addRule(new QueryComplexity($this->queryComplexity)); From 341d68cc42e6a06cfdccf2d1fcb4475f69bb9318 Mon Sep 17 00:00:00 2001 From: RomanKis <romaikiss@gmail.com> Date: Tue, 5 Dec 2017 18:01:25 +0200 Subject: [PATCH 051/812] MAGETWO-94308: User can place order with amount less than "minimum order amount" via Checkout with multiple address flow. - Upport fix from 2.2-develop --- .../Model/Checkout/Type/Multishipping.php | 53 +++++++++++++++++-- .../Model/Checkout/Type/MultishippingTest.php | 42 ++++++++++++++- 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php index 9412b13895599..8d740b4ea6b92 100644 --- a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php +++ b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php @@ -897,13 +897,21 @@ public function reset() */ public function validateMinimumAmount() { - return !($this->_scopeConfig->isSetFlag( + $minimumOrderActive = $this->_scopeConfig->isSetFlag( 'sales/minimum_order/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ) && $this->_scopeConfig->isSetFlag( + ); + + if ($this->_scopeConfig->isSetFlag( 'sales/minimum_order/multi_address', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ) && !$this->getQuote()->validateMinimumAmount()); + \Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ) { + $result = !($minimumOrderActive && !$this->getQuote()->validateMinimumAmount()); + } else { + $result = !($minimumOrderActive && !$this->validateMinimumAmountForAddressItems()); + } + + return $result; } /** @@ -1115,6 +1123,43 @@ private function getShippingAssignmentProcessor() return $this->shippingAssignmentProcessor; } + /** + * Validate minimum amount for "Checkout with Multiple Addresses" when + * "Validate Each Address Separately in Multi-address Checkout" is No. + * + * @return bool + */ + private function validateMinimumAmountForAddressItems() + { + $result = true; + $storeId = $this->getQuote()->getStoreId(); + + $minAmount = $this->_scopeConfig->getValue( + 'sales/minimum_order/amount', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $storeId + ); + $taxInclude = $this->_scopeConfig->getValue( + 'sales/minimum_order/tax_including', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $storeId + ); + + $addresses = $this->getQuote()->getAllAddresses(); + + $baseTotal = 0; + foreach ($addresses as $address) { + $taxes = $taxInclude ? $address->getBaseTaxAmount() : 0; + $baseTotal += $address->getBaseSubtotalWithDiscount() + $taxes; + } + + if ($baseTotal < $minAmount) { + $result = false; + } + + return $result; + } + /** * Remove successfully placed items from quote. * diff --git a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php index 94c11bef1d311..da206cf266219 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php @@ -167,13 +167,18 @@ class MultishippingTest extends \PHPUnit\Framework\TestCase */ private $sessionMock; + /** + * @var PHPUnit_Framework_MockObject_MockObject + */ + private $scopeConfigMock; + protected function setUp() { $this->checkoutSessionMock = $this->createSimpleMock(Session::class); $this->customerSessionMock = $this->createSimpleMock(CustomerSession::class); $this->orderFactoryMock = $this->createSimpleMock(OrderFactory::class); $eventManagerMock = $this->createSimpleMock(ManagerInterface::class); - $scopeConfigMock = $this->createSimpleMock(ScopeConfigInterface::class); + $this->scopeConfigMock = $this->createSimpleMock(ScopeConfigInterface::class); $this->sessionMock = $this->createSimpleMock(Generic::class); $addressFactoryMock = $this->createSimpleMock(AddressFactory::class); $this->toOrderMock = $this->createSimpleMock(ToOrder::class); @@ -224,7 +229,7 @@ protected function setUp() $this->orderFactoryMock, $this->addressRepositoryMock, $eventManagerMock, - $scopeConfigMock, + $this->scopeConfigMock, $this->sessionMock, $addressFactoryMock, $this->toOrderMock, @@ -807,4 +812,37 @@ private function createSimpleMock($className) ->disableOriginalConstructor() ->getMock(); } + + public function testValidateMinimumAmountMultiAddressTrue() + { + $this->scopeConfigMock->expects($this->exactly(2))->method('isSetFlag')->withConsecutive( + ['sales/minimum_order/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE], + ['sales/minimum_order/multi_address', \Magento\Store\Model\ScopeInterface::SCOPE_STORE] + )->willReturnOnConsecutiveCalls(true, true); + + $this->checkoutSessionMock->expects($this->atLeastOnce())->method('getQuote')->willReturn($this->quoteMock); + $this->quoteMock->expects($this->once())->method('validateMinimumAmount')->willReturn(false); + $this->assertFalse($this->model->validateMinimumAmount()); + } + + public function testValidateMinimumAmountMultiAddressFalse() + { + $addressMock = $this->createMock(\Magento\Quote\Model\Quote\Address::class); + $this->scopeConfigMock->expects($this->exactly(2))->method('isSetFlag')->withConsecutive( + ['sales/minimum_order/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE], + ['sales/minimum_order/multi_address', \Magento\Store\Model\ScopeInterface::SCOPE_STORE] + )->willReturnOnConsecutiveCalls(true, false); + + $this->scopeConfigMock->expects($this->exactly(2))->method('getValue')->withConsecutive( + ['sales/minimum_order/amount', \Magento\Store\Model\ScopeInterface::SCOPE_STORE], + ['sales/minimum_order/tax_including', \Magento\Store\Model\ScopeInterface::SCOPE_STORE] + )->willReturnOnConsecutiveCalls(100, false); + + $this->checkoutSessionMock->expects($this->atLeastOnce())->method('getQuote')->willReturn($this->quoteMock); + $this->quoteMock->expects($this->once())->method('getStoreId')->willReturn(1); + $this->quoteMock->expects($this->once())->method('getAllAddresses')->willReturn([$addressMock]); + $addressMock->expects($this->once())->method('getBaseSubtotalWithDiscount')->willReturn(101); + + $this->assertTrue($this->model->validateMinimumAmount()); + } } From e323c7b3661191c9eeb52776ab1b4c0c6fb5d8ad Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Mon, 17 Sep 2018 14:50:10 -0500 Subject: [PATCH 052/812] MAGETWO-94308: User can place order with amount less than "minimum order amount" via Checkout with multiple address flow. - Fix issue with upport that doesn't trigger totals to re-calculate before validation - Remove redundant form markup from addresses template - Update unit test to account for changes --- .../Model/Checkout/Type/Multishipping.php | 3 ++- .../Unit/Model/Checkout/Type/MultishippingTest.php | 8 ++++++++ .../view/frontend/templates/checkout/addresses.phtml | 11 ----------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php index 8d740b4ea6b92..f55af40388fdf 100644 --- a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php +++ b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php @@ -874,7 +874,7 @@ private function logExceptions(array $exceptionList) */ public function save() { - $this->getQuote()->collectTotals(); + $this->getQuote()->setTotalsCollectedFlag(false)->collectTotals(); $this->quoteRepository->save($this->getQuote()); return $this; } @@ -1145,6 +1145,7 @@ private function validateMinimumAmountForAddressItems() $storeId ); + $this->getQuote()->collectTotals(); $addresses = $this->getQuote()->getAllAddresses(); $baseTotal = 0; diff --git a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php index da206cf266219..67ff233f717eb 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php @@ -282,6 +282,10 @@ public function testSetShippingItemsInformation() ->willReturn(null); $this->quoteMock->expects($this->atLeastOnce())->method('getAllItems')->willReturn([]); + $this->quoteMock->expects($this->once()) + ->method('__call') + ->with('setTotalsCollectedFlag', [false]) + ->willReturnSelf(); $this->filterBuilderMock->expects($this->atLeastOnce())->method('setField')->willReturnSelf(); $this->filterBuilderMock->expects($this->atLeastOnce())->method('setValue')->willReturnSelf(); @@ -421,6 +425,10 @@ public function testSetShippingMethods() $addressMock->expects($this->once())->method('getId')->willReturn($addressId); $this->quoteMock->expects($this->once())->method('getAllShippingAddresses')->willReturn([$addressMock]); $addressMock->expects($this->once())->method('setShippingMethod')->with($methodsArray[$addressId]); + $this->quoteMock->expects($this->once()) + ->method('__call') + ->with('setTotalsCollectedFlag', [false]) + ->willReturnSelf(); $this->mockShippingAssignment(); diff --git a/app/code/Magento/Multishipping/view/frontend/templates/checkout/addresses.phtml b/app/code/Magento/Multishipping/view/frontend/templates/checkout/addresses.phtml index 0f96f7cdb708a..a29013cc71722 100644 --- a/app/code/Magento/Multishipping/view/frontend/templates/checkout/addresses.phtml +++ b/app/code/Magento/Multishipping/view/frontend/templates/checkout/addresses.phtml @@ -14,17 +14,6 @@ * @var $block \Magento\Multishipping\Block\Checkout\Addresses */ ?> -<form id="checkout_multishipping_form" - data-mage-init='{ - "multiShipping":{}, - "validation":{}, - "cartUpdate": { - "validationURL": "/multishipping/checkout/checkItems", - "eventName": "updateMulticartItemQty" - }}' - action="<?= $block->escapeUrl($block->getPostActionUrl()) ?>" - method="post" - class="multicheckout address form"> <form id="checkout_multishipping_form" data-mage-init='{ "multiShipping":{}, From 5372c7df5e16601f2cce687e15ff25ecdd0b82ce Mon Sep 17 00:00:00 2001 From: lucascalazans <calazans95@hotmail.com> Date: Mon, 17 Sep 2018 17:18:04 -0300 Subject: [PATCH 053/812] #17744 Fixing syntax pattern --- .../view/frontend/web/js/model/checkout-data-resolver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 7a1ba9513ec42..6f4c99438610b 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -227,7 +227,7 @@ define([ return; } - if(quote.isVirtual()) { + if (quote.isVirtual()) { isBillingAddressInitialized = addressList.some(function (addrs) { if (addrs.isDefaultBilling()) { selectBillingAddress(addrs); From 7ddff219604b24bfc73b5890bf2db4147b79d6e2 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Thu, 13 Sep 2018 17:07:20 +0300 Subject: [PATCH 054/812] MAGETWO-94482: Fixed procedure of creating mapping for dynamic fields in elasticsearch --- .../CategoryFieldsProvider.php | 16 +- .../Adapter/DataMapper/ProductDataMapper.php | 12 +- .../FieldMapper/ProductFieldMapper.php | 207 +++++++----------- .../CategoryFieldsProvider.php | 16 +- .../BatchDataMapper/PriceFieldsProvider.php | 21 +- .../Adapter/DataMapper/ProductDataMapper.php | 36 +-- .../Model/Adapter/Elasticsearch.php | 7 +- .../FieldNameResolverPoolInterface.php | 23 ++ .../FieldName/Resolver/CategoryName.php | 66 ++++++ .../FieldName/Resolver/DefaultResolver.php | 102 +++++++++ .../FieldName/Resolver/NotEavAttribute.php | 23 ++ .../Product/FieldName/Resolver/Position.php | 66 ++++++ .../Product/FieldName/Resolver/Price.php | 42 ++++ .../FieldName/Resolver/SpecialAttribute.php | 23 ++ .../Product/FieldName/ResolverInterface.php | 19 ++ .../Specification/CategoryNameAttribute.php | 29 +++ .../Specification/DummySpecification.php | 25 +++ .../Specification/NotEavAttribute.php | 47 ++++ .../Specification/PositionAttribute.php | 29 +++ .../Specification/PriceAttribute.php | 29 +++ .../Specification/SpecialAttribute.php | 29 +++ .../FieldName/Specification/Specification.php | 54 +++++ .../FieldName/SpecificationInterface.php | 38 ++++ .../Product/FieldNameResolverPool.php | 56 +++++ .../FieldMapper/ProductFieldMapper.php | 93 +------- app/code/Magento/Elasticsearch/etc/di.xml | 40 ++++ 26 files changed, 877 insertions(+), 271 deletions(-) create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 009c07602fc2a..3e6164208b422 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -7,6 +7,7 @@ use Magento\Elasticsearch\Model\ResourceModel\Index; use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; /** * Provide data mapping for categories fields @@ -18,12 +19,19 @@ class CategoryFieldsProvider implements AdditionalFieldsProviderInterface */ private $resourceIndex; + /** + * @var FieldMapperInterface + */ + private $fieldMapper; + /** * @param Index $resourceIndex + * @param FieldMapperInterface $fieldMapper */ - public function __construct(Index $resourceIndex) + public function __construct(Index $resourceIndex, FieldMapperInterface $fieldMapper) { $this->resourceIndex = $resourceIndex; + $this->fieldMapper = $fieldMapper; } /** @@ -59,8 +67,10 @@ private function getProductCategoryData($productId, array $categoryIndexData) if (count($categoryIds)) { $result = ['category_ids' => $categoryIds]; foreach ($indexData as $data) { - $result['position_category_' . $data['id']] = $data['position']; - $result['name_category_' . $data['id']] = $data['name']; + $categoryPositionKey = $this->fieldMapper->getFieldName('position', ['categoryId' => $data['id']]); + $categoryNameKey = $this->fieldMapper->getFieldName('category_name', ['categoryId' => $data['id']]); + $result[$categoryPositionKey] = $data['position']; + $result[$categoryNameKey] = $data['name']; } } } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php index 659df0f8447f9..bcf0d0bfe26cd 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php @@ -364,9 +364,11 @@ protected function getProductPriceData($productId, $storeId, array $priceIndexDa $result = []; if (array_key_exists($productId, $priceIndexData)) { $productPriceIndexData = $priceIndexData[$productId]; - $websiteId = $this->storeManager->getStore($storeId)->getWebsiteId(); foreach ($productPriceIndexData as $customerGroupId => $price) { - $fieldName = 'price_' . $customerGroupId . '_' . $websiteId; + $fieldName = $this->fieldMapper->getFieldName( + 'price', + ['customerGroupId' => $customerGroupId] + ); $result[$fieldName] = sprintf('%F', $price); } } @@ -398,8 +400,10 @@ protected function getProductCategoryData($productId, array $categoryIndexData) if (count($categoryIds)) { $result = ['category_ids' => implode(' ', $categoryIds)]; foreach ($indexData as $data) { - $result['position_category_' . $data['id']] = $data['position']; - $result['name_category_' . $data['id']] = $data['name']; + $categoryPositionKey = $this->fieldMapper->getFieldName('position', ['categoryId' => $data['id']]); + $categoryNameKey = $this->fieldMapper->getFieldName('category_name', ['categoryId' => $data['id']]); + $result[$categoryPositionKey] = $data['position']; + $result[$categoryNameKey] = $data['name']; } } } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php index be198e7190ec9..247eb624b2a56 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -5,13 +5,14 @@ */ namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper; +use Magento\Catalog\Api\CategoryListInterface; use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Eav\Model\Config; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldNameResolverPoolInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; -use Magento\Framework\Registry; -use Magento\Store\Model\StoreManagerInterface as StoreManager; -use \Magento\Customer\Model\Session as CustomerSession; +use Magento\Framework\Api\SearchCriteriaBuilder; /** * Class ProductFieldMapper @@ -29,43 +30,50 @@ class ProductFieldMapper implements FieldMapperInterface protected $fieldType; /** - * @var CustomerSession + * Category list. + * + * @var CategoryListInterface */ - protected $customerSession; + private $categoryList; /** - * Store manager + * Customer group repository. * - * @var StoreManager + * @var GroupRepositoryInterface */ - protected $storeManager; + private $groupRepository; /** - * Core registry + * Search criteria builder. * - * @var Registry + * @var SearchCriteriaBuilder */ - protected $coreRegistry; + private $searchCriteriaBuilder; + + /** + * @var FieldNameResolverPoolInterface + */ + private $fieldNameResolverPool; /** * @param Config $eavConfig * @param FieldType $fieldType - * @param CustomerSession $customerSession - * @param StoreManager $storeManager - * @param Registry $coreRegistry + * @param GroupRepositoryInterface $groupRepository + * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param FieldNameResolverPoolInterface $fieldNameResolverPool */ public function __construct( Config $eavConfig, FieldType $fieldType, - CustomerSession $customerSession, - StoreManager $storeManager, - Registry $coreRegistry + GroupRepositoryInterface $groupRepository, + SearchCriteriaBuilder $searchCriteriaBuilder, + FieldNameResolverPoolInterface $fieldNameResolverPool ) { $this->eavConfig = $eavConfig; $this->fieldType = $fieldType; - $this->customerSession = $customerSession; - $this->storeManager = $storeManager; - $this->coreRegistry = $coreRegistry; + $this->groupRepository = $groupRepository; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->fieldNameResolverPool = $fieldNameResolverPool; } /** @@ -77,35 +85,7 @@ public function __construct( */ public function getFieldName($attributeCode, $context = []) { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - if (!$attribute || in_array($attributeCode, ['id', 'sku', 'store_id', 'visibility'], true)) { - return $attributeCode; - } - if ($attributeCode === 'price') { - return $this->getPriceFieldName($context); - } - if ($attributeCode === 'position') { - return $this->getPositionFiledName($context); - } - $fieldType = $this->fieldType->getFieldType($attribute); - $frontendInput = $attribute->getFrontendInput(); - if (empty($context['type'])) { - $fieldName = $attributeCode; - } elseif ($context['type'] === FieldMapperInterface::TYPE_FILTER) { - if ($fieldType === FieldType::ES_DATA_TYPE_TEXT) { - return $this->getFieldName( - $attributeCode, - array_merge($context, ['type' => FieldMapperInterface::TYPE_QUERY]) - ); - } - $fieldName = $attributeCode; - } elseif ($context['type'] === FieldMapperInterface::TYPE_QUERY) { - $fieldName = $this->getQueryTypeFieldName($frontendInput, $fieldType, $attributeCode); - } else { - $fieldName = 'sort_' . $attributeCode; - } - - return $fieldName; + return $this->fieldNameResolverPool->getResolver($attributeCode)->getFieldName($attributeCode, $context); } /** @@ -113,10 +93,33 @@ public function getFieldName($attributeCode, $context = []) * * @param array $context * @return array - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function getAllAttributesTypes($context = []) + { + return array_merge( + $this->getAllStaticAttributesTypes(), + $this->getAllDynamicAttributesTypes() + ); + } + + /** + * @param Object $attribute + * @return bool + */ + protected function isAttributeUsedInAdvancedSearch($attribute) + { + return $attribute->getIsVisibleInAdvancedSearch() + || $attribute->getIsFilterable() + || $attribute->getIsFilterableInSearch(); + } + + /** + * Prepare mapping data for static attributes. + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @return array + */ + private function getAllStaticAttributesTypes() { $attributeCodes = $this->eavConfig->getEntityAttributeCodes(ProductAttributeInterface::ENTITY_TYPE_CODE); $allAttributes = []; @@ -163,89 +166,37 @@ public function getAllAttributesTypes($context = []) } /** - * Is attribute used in advanced search. + * Prepare mapping data for dynamic attributes. * - * @param Object $attribute - * @return bool - */ - protected function isAttributeUsedInAdvancedSearch($attribute) - { - return $attribute->getIsVisibleInAdvancedSearch() - || $attribute->getIsFilterable() - || $attribute->getIsFilterableInSearch(); - } - - /** - * Get refined field name. - * - * @param string $frontendInput - * @param string $fieldType - * @param string $attributeCode - * @return string - */ - protected function getRefinedFieldName($frontendInput, $fieldType, $attributeCode) - { - switch ($frontendInput) { - case 'select': - case 'multiselect': - return in_array($fieldType, ['text','integer'], true) ? $attributeCode . '_value' : $attributeCode; - case 'boolean': - return $fieldType === 'integer' ? $attributeCode . '_value' : $attributeCode; - default: - return $attributeCode; - } - } - - /** - * Get query type field name. - * - * @param string $frontendInput - * @param string $fieldType - * @param string $attributeCode - * @return string + * @return array */ - protected function getQueryTypeFieldName($frontendInput, $fieldType, $attributeCode) + private function getAllDynamicAttributesTypes() { - if ($attributeCode === '*') { - $fieldName = '_all'; - } else { - $fieldName = $this->getRefinedFieldName($frontendInput, $fieldType, $attributeCode); + $allAttributes = []; + $searchCriteria = $this->searchCriteriaBuilder->create(); + $categories = $this->categoryList->getList($searchCriteria)->getItems(); + foreach ($categories as $category) { + $categoryPositionKey = $this->getFieldName('position', ['categoryId' => $category->getId()]); + $categoryNameKey = $this->getFieldName('category_name', ['categoryId' => $category->getId()]); + $allAttributes[$categoryPositionKey] = [ + 'type' => FieldType::ES_DATA_TYPE_TEXT, + 'index' => false + ]; + $allAttributes[$categoryNameKey] = [ + 'type' => FieldType::ES_DATA_TYPE_TEXT, + 'index' => false + ]; } - return $fieldName; - } - /** - * Get "position" field name - * - * @param array $context - * @return string - */ - protected function getPositionFiledName($context) - { - if (isset($context['categoryId'])) { - $category = $context['categoryId']; - } else { - $category = $this->coreRegistry->registry('current_category') - ? $this->coreRegistry->registry('current_category')->getId() - : $this->storeManager->getStore()->getRootCategoryId(); + $groups = $this->groupRepository->getList($searchCriteria)->getItems(); + foreach ($groups as $group) { + $groupPriceKey = $this->getFieldName('price', ['customerGroupId' => $group->getId()]); + $allAttributes[$groupPriceKey] = [ + 'type' => FieldType::ES_DATA_TYPE_FLOAT, + 'store' => true + ]; } - return 'position_category_' . $category; - } - /** - * Prepare price field name for search engine - * - * @param array $context - * @return string - */ - protected function getPriceFieldName($context) - { - $customerGroupId = !empty($context['customerGroupId']) - ? $context['customerGroupId'] - : $this->customerSession->getCustomerGroupId(); - $websiteId = !empty($context['websiteId']) - ? $context['websiteId'] - : $this->storeManager->getStore()->getWebsiteId(); - return 'price_' . $customerGroupId . '_' . $websiteId; + return $allAttributes; } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index e2de4aec717a4..7d2af3b31d9ac 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -7,6 +7,7 @@ use Magento\Elasticsearch\Model\ResourceModel\Index; use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; /** * Provide data mapping for categories fields @@ -18,12 +19,19 @@ class CategoryFieldsProvider implements AdditionalFieldsProviderInterface */ private $resourceIndex; + /** + * @var FieldMapperInterface + */ + private $fieldMapper; + /** * @param Index $resourceIndex + * @param FieldMapperInterface $fieldMapper */ - public function __construct(Index $resourceIndex) + public function __construct(Index $resourceIndex, FieldMapperInterface $fieldMapper) { $this->resourceIndex = $resourceIndex; + $this->fieldMapper = $fieldMapper; } /** @@ -59,8 +67,10 @@ private function getProductCategoryData($productId, array $categoryIndexData) if (count($categoryIds)) { $result = ['category_ids' => implode(' ', $categoryIds)]; foreach ($indexData as $data) { - $result['position_category_' . $data['id']] = $data['position']; - $result['name_category_' . $data['id']] = $data['name']; + $categoryPositionKey = $this->fieldMapper->getFieldName('position', ['categoryId' => $data['id']]); + $categoryNameKey = $this->fieldMapper->getFieldName('category_name', ['categoryId' => $data['id']]); + $result[$categoryPositionKey] = $data['position']; + $result[$categoryNameKey] = $data['name']; } } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php index f5e8a23525a07..f97cc89c5c875 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php @@ -5,6 +5,7 @@ */ namespace Magento\Elasticsearch\Model\Adapter\BatchDataMapper; +use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\Model\ResourceModel\Index; use Magento\Store\Model\StoreManagerInterface; use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; @@ -30,19 +31,27 @@ class PriceFieldsProvider implements AdditionalFieldsProviderInterface */ private $storeManager; + /** + * @var FieldMapperInterface + */ + private $fieldMapper; + /** * @param Index $resourceIndex * @param DataProvider $dataProvider * @param StoreManagerInterface $storeManager + * @param FieldMapperInterface $fieldMapper */ public function __construct( Index $resourceIndex, DataProvider $dataProvider, - StoreManagerInterface $storeManager + StoreManagerInterface $storeManager, + FieldMapperInterface $fieldMapper ) { $this->resourceIndex = $resourceIndex; $this->dataProvider = $dataProvider; $this->storeManager = $storeManager; + $this->fieldMapper = $fieldMapper; } /** @@ -56,7 +65,7 @@ public function getFields(array $productIds, $storeId) $fields = []; foreach ($productIds as $productId) { - $fields[$productId] = $this->getProductPriceData($productId, $storeId, $priceData); + $fields[$productId] = $this->getProductPriceData($productId, $priceData); } return $fields; @@ -66,17 +75,19 @@ public function getFields(array $productIds, $storeId) * Prepare price index for product * * @param int $productId - * @param int $websiteId * @param array $priceIndexData * @return array */ - private function getProductPriceData($productId, $websiteId, array $priceIndexData) + private function getProductPriceData($productId, array $priceIndexData) { $result = []; if (array_key_exists($productId, $priceIndexData)) { $productPriceIndexData = $priceIndexData[$productId]; foreach ($productPriceIndexData as $customerGroupId => $price) { - $fieldName = 'price_' . $customerGroupId . '_' . $websiteId; + $fieldName = $this->fieldMapper->getFieldName( + 'price', + ['customerGroupId' => $customerGroupId] + ); $result[$fieldName] = sprintf('%F', $price); } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php index da37c8d7647d8..1ca24a0c73025 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php @@ -5,9 +5,6 @@ */ namespace Magento\Elasticsearch\Model\Adapter\DataMapper; -use Magento\Catalog\Model\ResourceModel\Eav\Attribute; -use Magento\Store\Model\StoreManagerInterface; -use Magento\Customer\Api\Data\GroupInterface; use Magento\Elasticsearch\Model\Adapter\DataMapperInterface; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\DataMapper\ProductDataMapper as ElasticSearch5ProductDataMapper; @@ -17,36 +14,5 @@ */ class ProductDataMapper extends ElasticSearch5ProductDataMapper implements DataMapperInterface { - /** - * Prepare category index data for product - * - * @param int $productId - * @param array $categoryIndexData - * @return array - */ - protected function getProductCategoryData($productId, array $categoryIndexData) - { - $result = []; - $categoryIds = []; - - if (array_key_exists($productId, $categoryIndexData)) { - $indexData = $categoryIndexData[$productId]; - $result = $indexData; - } - - if (array_key_exists($productId, $categoryIndexData)) { - $indexData = $categoryIndexData[$productId]; - foreach ($indexData as $categoryData) { - $categoryIds[] = $categoryData['id']; - } - if (count($categoryIds)) { - $result = ['category_ids' => implode(' ', $categoryIds)]; - foreach ($indexData as $data) { - $result['position_category_' . $data['id']] = $data['position']; - $result['name_category_' . $data['id']] = $data['name']; - } - } - } - return $result; - } + // } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php index 7fc45eed35650..fdf23332fff04 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php @@ -347,9 +347,12 @@ public function updateAlias($storeId, $mappedIndexerId) protected function prepareIndex($storeId, $indexName, $mappedIndexerId) { $this->indexBuilder->setStoreId($storeId); - $this->client->createIndex($indexName, ['settings' => $this->indexBuilder->build()]); + $settings = $this->indexBuilder->build(); + $allAttributeTypes = $this->fieldMapper->getAllAttributesTypes(['entityType' => $mappedIndexerId]); + $settings['index']['mapping']['total_fields']['limit'] = count($allAttributeTypes); + $this->client->createIndex($indexName, ['settings' => $settings]); $this->client->addFieldsMapping( - $this->fieldMapper->getAllAttributesTypes(['entityType' => $mappedIndexerId]), + $allAttributeTypes, $indexName, $this->clientConfig->getEntityType() ); diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php new file mode 100644 index 0000000000000..50172e8381d59 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Identify field name resolver for attribute. + */ +interface FieldNameResolverPoolInterface +{ + /** + * Get field name resolver. + * + * @param string $attributeCode + * @param array $context + * @return ResolverInterface + */ + public function getResolver(string $attributeCode, $context = []) : ResolverInterface; +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php new file mode 100644 index 0000000000000..8b3c79f66e38a --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; + +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Resolver field name for Category name attribute. + */ +class CategoryName implements ResolverInterface +{ + /** + * @var StoreManager + */ + private $storeManager; + + /** + * @var Registry + */ + private $coreRegistry; + + /** + * @param StoreManager $storeManager + * @param Registry $coreRegistry + */ + public function __construct( + StoreManager $storeManager, + Registry $coreRegistry + ) { + $this->storeManager = $storeManager; + $this->coreRegistry = $coreRegistry; + } + + /** + * {@inheritdoc} + */ + public function getFieldName($attributeCode, $context = []) + { + return 'name_category_' . $this->resolveCategoryId($context); + } + + /** + * Resolve category id. + * + * @param array $context + * @return int + */ + private function resolveCategoryId($context) + { + if (isset($context['categoryId'])) { + $id = $context['categoryId']; + } else { + $id = $this->coreRegistry->registry('current_category') + ? $this->coreRegistry->registry('current_category')->getId() + : $this->storeManager->getStore()->getRootCategoryId(); + } + + return $id; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php new file mode 100644 index 0000000000000..d62354daf7638 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php @@ -0,0 +1,102 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; + +use Magento\Eav\Model\Config; +use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; +use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Default name resolver. + */ +class DefaultResolver implements ResolverInterface +{ + /** + * @var Config + */ + private $eavConfig; + + /** + * @var FieldType + */ + private $fieldType; + + /** + * @param Config $eavConfig + * @param FieldType $fieldType + */ + public function __construct( + Config $eavConfig, + FieldType $fieldType + ) { + $this->eavConfig = $eavConfig; + $this->fieldType = $fieldType; + } + + /** + * {@inheritdoc} + */ + public function getFieldName($attributeCode, $context = []) + { + $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); + $fieldType = $this->fieldType->getFieldType($attribute); + $frontendInput = $attribute->getFrontendInput(); + if (empty($context['type'])) { + $fieldName = $attributeCode; + } elseif ($context['type'] === FieldMapperInterface::TYPE_FILTER) { + if (in_array($fieldType, ['string', FieldType::ES_DATA_TYPE_TEXT], true)) { + return $this->getFieldName( + $attributeCode, + array_merge($context, ['type' => FieldMapperInterface::TYPE_QUERY]) + ); + } + $fieldName = $attributeCode; + } elseif ($context['type'] === FieldMapperInterface::TYPE_QUERY) { + $fieldName = $this->getQueryTypeFieldName($frontendInput, $fieldType, $attributeCode); + } else { + $fieldName = 'sort_' . $attributeCode; + } + + return $fieldName; + } + + /** + * @param string $frontendInput + * @param string $fieldType + * @param string $attributeCode + * @return string + */ + private function getQueryTypeFieldName($frontendInput, $fieldType, $attributeCode) + { + if ($attributeCode === '*') { + $fieldName = '_all'; + } else { + $fieldName = $this->getRefinedFieldName($frontendInput, $fieldType, $attributeCode); + } + return $fieldName; + } + + /** + * @param string $frontendInput + * @param string $fieldType + * @param string $attributeCode + * @return string + */ + private function getRefinedFieldName($frontendInput, $fieldType, $attributeCode) + { + switch ($frontendInput) { + case 'select': + return in_array($fieldType, ['text','integer'], true) ? $attributeCode . '_value' : $attributeCode; + case 'boolean': + return $fieldType === 'integer' ? $attributeCode . '_value' : $attributeCode; + default: + return $attributeCode; + } + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php new file mode 100644 index 0000000000000..3c19ab7e216cc --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Resolver field name for not EAV attribute. + */ +class NotEavAttribute implements ResolverInterface +{ + /** + * {@inheritdoc} + */ + public function getFieldName($attributeCode, $context = []) + { + return $attributeCode; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php new file mode 100644 index 0000000000000..8082e48e57b5e --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; + +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Resolver field name for position attribute. + */ +class Position implements ResolverInterface +{ + /** + * @var StoreManager + */ + private $storeManager; + + /** + * @var Registry + */ + private $coreRegistry; + + /** + * @param StoreManager $storeManager + * @param Registry $coreRegistry + */ + public function __construct( + StoreManager $storeManager, + Registry $coreRegistry + ) { + $this->storeManager = $storeManager; + $this->coreRegistry = $coreRegistry; + } + + /** + * {@inheritdoc} + */ + public function getFieldName($attributeCode, $context = []) + { + return 'position_category_' . $this->resolveCategoryId($context); + } + + /** + * Resolve category id. + * + * @param array $context + * @return int + */ + private function resolveCategoryId($context) + { + if (isset($context['categoryId'])) { + $id = $context['categoryId']; + } else { + $id = $this->coreRegistry->registry('current_category') + ? $this->coreRegistry->registry('current_category')->getId() + : $this->storeManager->getStore()->getRootCategoryId(); + } + + return $id; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php new file mode 100644 index 0000000000000..0a09740e9747d --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; + +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Resolver field name for price attribute. + */ +class Price implements ResolverInterface +{ + /** + * @var CustomerSession + */ + private $customerSession; + + /** + * @param CustomerSession $customerSession + */ + public function __construct( + CustomerSession $customerSession + ) { + $this->customerSession = $customerSession; + } + + /** + * {@inheritdoc} + */ + public function getFieldName($attributeCode, $context = []) + { + $customerGroupId = !empty($context['customerGroupId']) + ? $context['customerGroupId'] + : $this->customerSession->getCustomerGroupId(); + + return 'price_' . $customerGroupId; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php new file mode 100644 index 0000000000000..5318797db5f07 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Resolver field name for not special attribute. + */ +class SpecialAttribute implements ResolverInterface +{ + /** + * {@inheritdoc} + */ + public function getFieldName($attributeCode, $context = []) + { + return $attributeCode; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php new file mode 100644 index 0000000000000..8b04bd281a71f --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php @@ -0,0 +1,19 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName; + +interface ResolverInterface +{ + /** + * Get field name. + * + * @param $attributeCode + * @param array $context + * @return string + */ + public function getFieldName($attributeCode, $context = []); +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php new file mode 100644 index 0000000000000..918f465569a7f --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; + +/** + * Specification for the category name attribute. + */ +class CategoryNameAttribute extends Specification implements SpecificationInterface +{ + const TYPE = 'CATEGORY_NAME_ATTRIBUTE'; + + /** + * {@inheritdoc} + */ + public function resolve(string $attributeCode): string + { + if ($attributeCode === 'category_name') { + return self::TYPE; + } + + return $this->getNext()->resolve($attributeCode); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php new file mode 100644 index 0000000000000..1c003e64683a8 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; + +/** + * Dummy specification. + */ +class DummySpecification extends Specification implements SpecificationInterface +{ + const TYPE = 'DUMMY'; + + /** + * {@inheritdoc} + */ + public function resolve(string $attributeCode): string + { + return self::TYPE; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php new file mode 100644 index 0000000000000..27da660c54c9e --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php @@ -0,0 +1,47 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Eav\Model\Config; + +/** + * Class ProductFieldMapper + */ +class NotEavAttribute extends Specification implements SpecificationInterface +{ + const TYPE = 'NOT_EAV_ATTRIBUTE'; + + /** + * @var Config + */ + private $eavConfig; + + /** + * @param SpecificationInterface $specification + * @param Config $eavConfig + */ + public function __construct(SpecificationInterface $specification, Config $eavConfig) + { + parent::__construct($specification); + $this->eavConfig = $eavConfig; + } + + /** + * {@inheritdoc} + */ + public function resolve(string $attributeCode): string + { + $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); + if (!$attribute) { + return self::TYPE; + } + + return $this->getNext()->resolve($attributeCode); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php new file mode 100644 index 0000000000000..0af6ea796e042 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; + +/** + * Specification for the position attribute. + */ +class PositionAttribute extends Specification implements SpecificationInterface +{ + const TYPE = 'POSITION_ATTRIBUTE'; + + /** + * {@inheritdoc} + */ + public function resolve(string $attributeCode): string + { + if ($attributeCode === 'position') { + return self::TYPE; + } + + return $this->getNext()->resolve($attributeCode); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php new file mode 100644 index 0000000000000..ead561c0d5f8a --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; + +/** + * Specification for the price attribute. + */ +class PriceAttribute extends Specification implements SpecificationInterface +{ + const TYPE = 'PRICE_ATTRIBUTE'; + + /** + * {@inheritdoc} + */ + public function resolve(string $attributeCode): string + { + if ($attributeCode === 'price') { + return self::TYPE; + } + + return $this->getNext()->resolve($attributeCode); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php new file mode 100644 index 0000000000000..c96e447ea7cc5 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; + +/** + * Specification for the special attributes. + */ +class SpecialAttribute extends Specification implements SpecificationInterface +{ + const TYPE = 'SPECIAL_ATTRIBUTE'; + + /** + * {@inheritdoc} + */ + public function resolve(string $attributeCode): string + { + if (in_array($attributeCode, ['id', 'sku', 'store_id', 'visibility'], true)) { + return self::TYPE; + } + + return $this->getNext()->resolve($attributeCode); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php new file mode 100644 index 0000000000000..86462e31a7b58 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; +use Magento\Framework\Exception\NotFoundException; + +/** + * Abstract class for resolving type of specification. + */ +abstract class Specification implements SpecificationInterface +{ + /** + * @var SpecificationInterface + */ + private $next; + + /** + * @param SpecificationInterface $specification + */ + public function __construct(SpecificationInterface $specification) + { + $this->next = $specification; + } + + /** + * {@inheritdoc} + */ + public abstract function resolve(string $attributeCode): string; + + /** + * {@inheritdoc} + */ + public function getNext(): SpecificationInterface + { + if (!$this->hasNext()) { + throw new NotFoundException(__('Next specification not found.')); + } + + return $this->next; + } + + /** + * {@inheritdoc} + */ + public function hasNext(): bool + { + return null !== $this->next; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php new file mode 100644 index 0000000000000..2e397fbf76c50 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName; + +use Magento\Framework\Exception\NotFoundException; + +/** + * Resolve name of type specification. + */ +interface SpecificationInterface +{ + /** + * Get specification name. + * + * @param string $attributeCode + * @return string + */ + public function resolve(string $attributeCode): string; + + /** + * Get next specification. + * + * @return SpecificationInterface + * @throws NotFoundException + */ + public function getNext(): SpecificationInterface; + + /** + * Check if next specification present. + * + * @return bool + */ + public function hasNext(): bool; +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php new file mode 100644 index 0000000000000..93334bf4c40c3 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldNameResolverPoolInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; + +/** + * Pool of field name resolvers. + */ +class FieldNameResolverPool implements FieldNameResolverPoolInterface +{ + /** + * @var ResolverInterface[] + */ + private $map; + + /** + * @var SpecificationInterface + */ + private $specification; + + /** + * @param SpecificationInterface $specification + * @param array $map + */ + public function __construct( + SpecificationInterface $specification, + array $map + ) { + $this->specification = $specification; + $this->map = $map; + } + + /** + * Get field name resolver. + * + * @param string $attributeCode + * @param array $context + * @return ResolverInterface + */ + public function getResolver(string $attributeCode, $context = []): ResolverInterface + { + $specification = $this->specification->resolve($attributeCode, $context); + if (!isset($this->map[$specification])) { + $specification = 'default'; + } + + return $this->map[$specification]; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php index 12645d0341417..e78983c62f6d2 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -6,11 +6,7 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper; use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Eav\Model\Config; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; -use Magento\Framework\Registry; -use Magento\Store\Model\StoreManagerInterface as StoreManager; -use \Magento\Customer\Model\Session as CustomerSession; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\ProductFieldMapper as Elasticsearch5ProductFieldMapper; use Magento\Elasticsearch\Model\Adapter\FieldType; @@ -21,76 +17,12 @@ class ProductFieldMapper extends Elasticsearch5ProductFieldMapper implements FieldMapperInterface { /** - * @param Config $eavConfig - * @param FieldType $fieldType - * @param CustomerSession $customerSession - * @param StoreManager $storeManager - * @param Registry $coreRegistry - */ - public function __construct( - Config $eavConfig, - FieldType $fieldType, - CustomerSession $customerSession, - StoreManager $storeManager, - Registry $coreRegistry - ) { - $this->eavConfig = $eavConfig; - $this->fieldType = $fieldType; - $this->customerSession = $customerSession; - $this->storeManager = $storeManager; - $this->coreRegistry = $coreRegistry; - } - - /** - * Get field name. - * - * @param string $attributeCode - * @param array $context - * @return string - */ - public function getFieldName($attributeCode, $context = []) - { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - if (!$attribute || in_array($attributeCode, ['id', 'sku', 'store_id', 'visibility'], true)) { - return $attributeCode; - } - if ($attributeCode === 'price') { - return $this->getPriceFieldName($context); - } - if ($attributeCode === 'position') { - return $this->getPositionFiledName($context); - } - $fieldType = $this->fieldType->getFieldType($attribute); - $frontendInput = $attribute->getFrontendInput(); - if (empty($context['type'])) { - $fieldName = $attributeCode; - } elseif ($context['type'] === FieldMapperInterface::TYPE_FILTER) { - if ($fieldType === 'string') { - return $this->getFieldName( - $attributeCode, - array_merge($context, ['type' => FieldMapperInterface::TYPE_QUERY]) - ); - } - $fieldName = $attributeCode; - } elseif ($context['type'] === FieldMapperInterface::TYPE_QUERY) { - $fieldName = $this->getQueryTypeFieldName($frontendInput, $fieldType, $attributeCode); - } else { - $fieldName = 'sort_' . $attributeCode; - } - - return $fieldName; - } - - /** - * Get all attributes types. - * - * @param array $context * @return array */ - public function getAllAttributesTypes($context = []) + private function getAllStaticAttributesTypes() { - $attributeCodes = $this->eavConfig->getEntityAttributeCodes(ProductAttributeInterface::ENTITY_TYPE_CODE); $allAttributes = []; + $attributeCodes = $this->eavConfig->getEntityAttributeCodes(ProductAttributeInterface::ENTITY_TYPE_CODE); // List of attributes which are required to be indexable $alwaysIndexableAttributes = [ 'category_ids', @@ -122,25 +54,4 @@ public function getAllAttributesTypes($context = []) return $allAttributes; } - - /** - * Get refined field name. - * - * @param string $frontendInput - * @param string $fieldType - * @param string $attributeCode - * @return string - */ - protected function getRefinedFieldName($frontendInput, $fieldType, $attributeCode) - { - switch ($frontendInput) { - case 'select': - case 'multiselect': - return in_array($fieldType, ['string','integer'], true) ? $attributeCode . '_value' : $attributeCode; - case 'boolean': - return $fieldType === 'integer' ? $attributeCode . '_value' : $attributeCode; - default: - return $attributeCode; - } - } } diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index 0cfaba845fd6a..b27f4d7e42118 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -7,6 +7,8 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapperInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldNameResolverPoolInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldNameResolverPool" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute" /> <type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver"> <arguments> <argument name="fieldMappers" xsi:type="array"> @@ -271,4 +273,42 @@ </argument> </arguments> </type> + <type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldNameResolverPool"> + <arguments> + <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute</argument> + <argument name="map" xsi:type="array"> + <item name="default" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\DefaultResolver</item> + <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\SpecialAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Special</item> + <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\NotEavAttribute</item> + <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PriceAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Price</item> + <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\CategoryNameAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\CategoryName</item> + <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PositionAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Position</item> + </argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute"> + <arguments> + <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\SpecialAttribute</argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\SpecialAttribute"> + <arguments> + <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PriceAttribute</argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PriceAttribute"> + <arguments> + <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\CategoryNameAttribute</argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\CategoryNameAttribute"> + <arguments> + <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PositionAttribute</argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PositionAttribute"> + <arguments> + <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\DummySpecification</argument> + </arguments> + </type> </config> From 7c40efce41f49a0c84fb4200a5fa63295464716c Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Tue, 18 Sep 2018 10:14:07 +0300 Subject: [PATCH 055/812] MAGETWO-94482: Fixed procedure of creating mapping for dynamic fields in elasticsearch - refactor --- .../FieldMapper/ProductFieldMapper.php | 14 ++--- .../FieldNameResolverPoolInterface.php | 23 -------- .../FieldName/Resolver/CategoryName.php | 13 ++++- .../FieldName/Resolver/DefaultResolver.php | 7 ++- .../FieldName/Resolver/NotEavAttribute.php | 28 +++++++++- .../Product/FieldName/Resolver/Position.php | 13 ++++- .../Product/FieldName/Resolver/Price.php | 19 +++++-- .../Resolver.php} | 22 ++++---- .../FieldName/Resolver/SpecialAttribute.php | 10 +++- .../Product/FieldName/ResolverInterface.php | 22 +++++++- .../Specification/CategoryNameAttribute.php | 29 ---------- .../Specification/DummySpecification.php | 25 --------- .../Specification/NotEavAttribute.php | 47 ---------------- .../Specification/PositionAttribute.php | 29 ---------- .../Specification/PriceAttribute.php | 29 ---------- .../Specification/SpecialAttribute.php | 29 ---------- .../FieldName/SpecificationInterface.php | 38 ------------- .../Product/FieldNameResolverPool.php | 56 ------------------- app/code/Magento/Elasticsearch/etc/di.xml | 36 ++++-------- 19 files changed, 120 insertions(+), 369 deletions(-) delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php rename app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/{Specification/Specification.php => Resolver/Resolver.php} (53%) delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php index 247eb624b2a56..87112032e1e27 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -9,7 +9,7 @@ use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Eav\Model\Config; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldNameResolverPoolInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; use Magento\Framework\Api\SearchCriteriaBuilder; @@ -51,29 +51,29 @@ class ProductFieldMapper implements FieldMapperInterface private $searchCriteriaBuilder; /** - * @var FieldNameResolverPoolInterface + * @var ResolverInterface */ - private $fieldNameResolverPool; + private $fieldNameResolver; /** * @param Config $eavConfig * @param FieldType $fieldType * @param GroupRepositoryInterface $groupRepository * @param SearchCriteriaBuilder $searchCriteriaBuilder - * @param FieldNameResolverPoolInterface $fieldNameResolverPool + * @param ResolverInterface $fieldNameResolver */ public function __construct( Config $eavConfig, FieldType $fieldType, GroupRepositoryInterface $groupRepository, SearchCriteriaBuilder $searchCriteriaBuilder, - FieldNameResolverPoolInterface $fieldNameResolverPool + ResolverInterface $fieldNameResolver ) { $this->eavConfig = $eavConfig; $this->fieldType = $fieldType; $this->groupRepository = $groupRepository; $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->fieldNameResolverPool = $fieldNameResolverPool; + $this->fieldNameResolver = $fieldNameResolver; } /** @@ -85,7 +85,7 @@ public function __construct( */ public function getFieldName($attributeCode, $context = []) { - return $this->fieldNameResolverPool->getResolver($attributeCode)->getFieldName($attributeCode, $context); + return $this->fieldNameResolver->getFieldName($attributeCode, $context); } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php deleted file mode 100644 index 50172e8381d59..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/FieldNameResolverPoolInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; - -/** - * Identify field name resolver for attribute. - */ -interface FieldNameResolverPoolInterface -{ - /** - * Get field name resolver. - * - * @param string $attributeCode - * @param array $context - * @return ResolverInterface - */ - public function getResolver(string $attributeCode, $context = []) : ResolverInterface; -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php index 8b3c79f66e38a..9e012c1427218 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php @@ -13,7 +13,7 @@ /** * Resolver field name for Category name attribute. */ -class CategoryName implements ResolverInterface +class CategoryName extends Resolver implements ResolverInterface { /** * @var StoreManager @@ -26,13 +26,16 @@ class CategoryName implements ResolverInterface private $coreRegistry; /** + * @param ResolverInterface $resolver * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( + ResolverInterface $resolver, StoreManager $storeManager, Registry $coreRegistry ) { + parent::__construct($resolver); $this->storeManager = $storeManager; $this->coreRegistry = $coreRegistry; } @@ -40,9 +43,13 @@ public function __construct( /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []) + public function getFieldName($attributeCode, $context = []): string { - return 'name_category_' . $this->resolveCategoryId($context); + if ($attributeCode === 'category_name') { + return 'name_category_' . $this->resolveCategoryId($context); + } + + return $this->getNext()->getFieldName($attributeCode, $context); } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php index d62354daf7638..afc0b6a0c6f99 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php @@ -15,7 +15,7 @@ /** * Default name resolver. */ -class DefaultResolver implements ResolverInterface +class DefaultResolver extends Resolver implements ResolverInterface { /** * @var Config @@ -28,13 +28,16 @@ class DefaultResolver implements ResolverInterface private $fieldType; /** + * @param ResolverInterface $resolver * @param Config $eavConfig * @param FieldType $fieldType */ public function __construct( + ResolverInterface $resolver, Config $eavConfig, FieldType $fieldType ) { + parent::__construct($resolver); $this->eavConfig = $eavConfig; $this->fieldType = $fieldType; } @@ -42,7 +45,7 @@ public function __construct( /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []) + public function getFieldName($attributeCode, $context = []): string { $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); $fieldType = $this->fieldType->getFieldType($attribute); diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php index 3c19ab7e216cc..8c8b58943a5b3 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php @@ -7,17 +7,39 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Eav\Model\Config; /** * Resolver field name for not EAV attribute. */ -class NotEavAttribute implements ResolverInterface +class NotEavAttribute extends Resolver implements ResolverInterface { + /** + * @var Config + */ + private $eavConfig; + + /** + * @param ResolverInterface $resolver + * @param Config $eavConfig + */ + public function __construct(ResolverInterface $resolver, Config $eavConfig) + { + parent::__construct($resolver); + $this->eavConfig = $eavConfig; + } + /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []) + public function getFieldName($attributeCode, $context = []): string { - return $attributeCode; + $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); + if (!$attribute) { + return $attributeCode; + } + + return $this->getNext()->getFieldName($attributeCode, $context); } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php index 8082e48e57b5e..d4839012f0b8c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php @@ -13,7 +13,7 @@ /** * Resolver field name for position attribute. */ -class Position implements ResolverInterface +class Position extends Resolver implements ResolverInterface { /** * @var StoreManager @@ -26,13 +26,16 @@ class Position implements ResolverInterface private $coreRegistry; /** + * @param ResolverInterface $resolver * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( + ResolverInterface $resolver, StoreManager $storeManager, Registry $coreRegistry ) { + parent::__construct($resolver); $this->storeManager = $storeManager; $this->coreRegistry = $coreRegistry; } @@ -40,9 +43,13 @@ public function __construct( /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []) + public function getFieldName($attributeCode, $context = []): string { - return 'position_category_' . $this->resolveCategoryId($context); + if ($attributeCode === 'position') { + return 'position_category_' . $this->resolveCategoryId($context); + } + + return $this->getNext()->getFieldName($attributeCode, $context); } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php index 0a09740e9747d..ea64972868d0a 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php @@ -12,7 +12,7 @@ /** * Resolver field name for price attribute. */ -class Price implements ResolverInterface +class Price extends Resolver implements ResolverInterface { /** * @var CustomerSession @@ -20,23 +20,30 @@ class Price implements ResolverInterface private $customerSession; /** + * @param ResolverInterface $resolver * @param CustomerSession $customerSession */ public function __construct( + ResolverInterface $resolver, CustomerSession $customerSession ) { + parent::__construct($resolver); $this->customerSession = $customerSession; } /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []) + public function getFieldName($attributeCode, $context = []): string { - $customerGroupId = !empty($context['customerGroupId']) - ? $context['customerGroupId'] - : $this->customerSession->getCustomerGroupId(); + if ($attributeCode === 'price') { + $customerGroupId = !empty($context['customerGroupId']) + ? $context['customerGroupId'] + : $this->customerSession->getCustomerGroupId(); - return 'price_' . $customerGroupId; + return 'price_' . $customerGroupId; + } + + return $this->getNext()->getFieldName($attributeCode, $context); } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php similarity index 53% rename from app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php rename to app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php index 86462e31a7b58..492fc70848530 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/Specification.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php @@ -4,41 +4,41 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; use Magento\Framework\Exception\NotFoundException; /** - * Abstract class for resolving type of specification. + * Abstract class for resolving field name. */ -abstract class Specification implements SpecificationInterface +abstract class Resolver implements ResolverInterface { /** - * @var SpecificationInterface + * @var ResolverInterface */ private $next; /** - * @param SpecificationInterface $specification + * @param ResolverInterface $resolver */ - public function __construct(SpecificationInterface $specification) + public function __construct(ResolverInterface $resolver) { - $this->next = $specification; + $this->next = $resolver; } /** * {@inheritdoc} */ - public abstract function resolve(string $attributeCode): string; + public abstract function getFieldName($attributeCode, $context = []): string; /** * {@inheritdoc} */ - public function getNext(): SpecificationInterface + public function getNext(): ResolverInterface { if (!$this->hasNext()) { - throw new NotFoundException(__('Next specification not found.')); + throw new NotFoundException(__('Next resolver not found.')); } return $this->next; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php index 5318797db5f07..518cd548536b2 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php @@ -11,13 +11,17 @@ /** * Resolver field name for not special attribute. */ -class SpecialAttribute implements ResolverInterface +class SpecialAttribute extends Resolver implements ResolverInterface { /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []) + public function getFieldName($attributeCode, $context = []): string { - return $attributeCode; + if (in_array($attributeCode, ['id', 'sku', 'store_id', 'visibility'], true)) { + return $attributeCode; + } + + return $this->getNext()->getFieldName($attributeCode, $context); } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php index 8b04bd281a71f..0b7bc187ecd68 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php @@ -6,6 +6,11 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName; +use Magento\Framework\Exception\NotFoundException; + +/** + * Field name resolver interface. + */ interface ResolverInterface { /** @@ -15,5 +20,20 @@ interface ResolverInterface * @param array $context * @return string */ - public function getFieldName($attributeCode, $context = []); + public function getFieldName($attributeCode, $context = []): string; + + /** + * Get next resolver. + * + * @return ResolverInterface + * @throws NotFoundException + */ + public function getNext(): ResolverInterface; + + /** + * Check if next resolver present. + * + * @return bool + */ + public function hasNext(): bool; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php deleted file mode 100644 index 918f465569a7f..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/CategoryNameAttribute.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; - -/** - * Specification for the category name attribute. - */ -class CategoryNameAttribute extends Specification implements SpecificationInterface -{ - const TYPE = 'CATEGORY_NAME_ATTRIBUTE'; - - /** - * {@inheritdoc} - */ - public function resolve(string $attributeCode): string - { - if ($attributeCode === 'category_name') { - return self::TYPE; - } - - return $this->getNext()->resolve($attributeCode); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php deleted file mode 100644 index 1c003e64683a8..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/DummySpecification.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; - -/** - * Dummy specification. - */ -class DummySpecification extends Specification implements SpecificationInterface -{ - const TYPE = 'DUMMY'; - - /** - * {@inheritdoc} - */ - public function resolve(string $attributeCode): string - { - return self::TYPE; - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php deleted file mode 100644 index 27da660c54c9e..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/NotEavAttribute.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; -use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Eav\Model\Config; - -/** - * Class ProductFieldMapper - */ -class NotEavAttribute extends Specification implements SpecificationInterface -{ - const TYPE = 'NOT_EAV_ATTRIBUTE'; - - /** - * @var Config - */ - private $eavConfig; - - /** - * @param SpecificationInterface $specification - * @param Config $eavConfig - */ - public function __construct(SpecificationInterface $specification, Config $eavConfig) - { - parent::__construct($specification); - $this->eavConfig = $eavConfig; - } - - /** - * {@inheritdoc} - */ - public function resolve(string $attributeCode): string - { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - if (!$attribute) { - return self::TYPE; - } - - return $this->getNext()->resolve($attributeCode); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php deleted file mode 100644 index 0af6ea796e042..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PositionAttribute.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; - -/** - * Specification for the position attribute. - */ -class PositionAttribute extends Specification implements SpecificationInterface -{ - const TYPE = 'POSITION_ATTRIBUTE'; - - /** - * {@inheritdoc} - */ - public function resolve(string $attributeCode): string - { - if ($attributeCode === 'position') { - return self::TYPE; - } - - return $this->getNext()->resolve($attributeCode); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php deleted file mode 100644 index ead561c0d5f8a..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/PriceAttribute.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; - -/** - * Specification for the price attribute. - */ -class PriceAttribute extends Specification implements SpecificationInterface -{ - const TYPE = 'PRICE_ATTRIBUTE'; - - /** - * {@inheritdoc} - */ - public function resolve(string $attributeCode): string - { - if ($attributeCode === 'price') { - return self::TYPE; - } - - return $this->getNext()->resolve($attributeCode); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php deleted file mode 100644 index c96e447ea7cc5..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Specification/SpecialAttribute.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; - -/** - * Specification for the special attributes. - */ -class SpecialAttribute extends Specification implements SpecificationInterface -{ - const TYPE = 'SPECIAL_ATTRIBUTE'; - - /** - * {@inheritdoc} - */ - public function resolve(string $attributeCode): string - { - if (in_array($attributeCode, ['id', 'sku', 'store_id', 'visibility'], true)) { - return self::TYPE; - } - - return $this->getNext()->resolve($attributeCode); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php deleted file mode 100644 index 2e397fbf76c50..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/SpecificationInterface.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName; - -use Magento\Framework\Exception\NotFoundException; - -/** - * Resolve name of type specification. - */ -interface SpecificationInterface -{ - /** - * Get specification name. - * - * @param string $attributeCode - * @return string - */ - public function resolve(string $attributeCode): string; - - /** - * Get next specification. - * - * @return SpecificationInterface - * @throws NotFoundException - */ - public function getNext(): SpecificationInterface; - - /** - * Check if next specification present. - * - * @return bool - */ - public function hasNext(): bool; -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php deleted file mode 100644 index 93334bf4c40c3..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldNameResolverPool.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldNameResolverPoolInterface; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; - -/** - * Pool of field name resolvers. - */ -class FieldNameResolverPool implements FieldNameResolverPoolInterface -{ - /** - * @var ResolverInterface[] - */ - private $map; - - /** - * @var SpecificationInterface - */ - private $specification; - - /** - * @param SpecificationInterface $specification - * @param array $map - */ - public function __construct( - SpecificationInterface $specification, - array $map - ) { - $this->specification = $specification; - $this->map = $map; - } - - /** - * Get field name resolver. - * - * @param string $attributeCode - * @param array $context - * @return ResolverInterface - */ - public function getResolver(string $attributeCode, $context = []): ResolverInterface - { - $specification = $this->specification->resolve($attributeCode, $context); - if (!isset($this->map[$specification])) { - $specification = 'default'; - } - - return $this->map[$specification]; - } -} diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index b27f4d7e42118..18772756b12a2 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -7,8 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapperInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver" /> - <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldNameResolverPoolInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldNameResolverPool" /> - <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\SpecificationInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\NotEavAttribute" /> <type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver"> <arguments> <argument name="fieldMappers" xsi:type="array"> @@ -273,42 +272,29 @@ </argument> </arguments> </type> - <type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldNameResolverPool"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\NotEavAttribute"> <arguments> - <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute</argument> - <argument name="map" xsi:type="array"> - <item name="default" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\DefaultResolver</item> - <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\SpecialAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Special</item> - <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\NotEavAttribute</item> - <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PriceAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Price</item> - <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\CategoryNameAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\CategoryName</item> - <item name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PositionAttribute::TYPE" xsi:type="string">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Position</item> - </argument> - </arguments> - </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\NotEavAttribute"> - <arguments> - <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\SpecialAttribute</argument> + <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\SpecialAttribute</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\SpecialAttribute"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\SpecialAttribute"> <arguments> - <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PriceAttribute</argument> + <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Price</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PriceAttribute"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Price"> <arguments> - <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\CategoryNameAttribute</argument> + <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\CategoryName</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\CategoryNameAttribute"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\CategoryName"> <arguments> - <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PositionAttribute</argument> + <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Position</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\PositionAttribute"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Position"> <arguments> - <argument name="specification" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Specification\DummySpecification</argument> + <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\DefaultResolver</argument> </arguments> </type> </config> From b871ea91610bd14c57ee99aa520ed7350c65b584 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <strpwebstudio@gmail.com> Date: Tue, 18 Sep 2018 10:34:27 +0300 Subject: [PATCH 056/812] #17744 Adding logic to get default billing address Fixed var declaration --- .../view/frontend/web/js/model/checkout-data-resolver.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 6f4c99438610b..142f6af91cc29 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -218,8 +218,8 @@ define([ * Apply resolved billing address to quote */ applyBillingAddress: function () { - var shippingAddress; - var isBillingAddressInitialized; + var shippingAddress, + isBillingAddressInitialized; if (quote.billingAddress()) { selectBillingAddress(quote.billingAddress()); From 540397d5f61fa76d1f6bc64c0c36dc4baaeebb40 Mon Sep 17 00:00:00 2001 From: Dave Macaulay <dmacaulay@magento.com> Date: Tue, 18 Sep 2018 12:32:24 +0200 Subject: [PATCH 057/812] MC-4189: IE11 - PageBuilder Does Not Load - Fix IE 11 loading of TinyMCE --- lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js index 223c6d6ab04ea..06943b25de55e 100644 --- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js +++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js @@ -30,7 +30,7 @@ define([ _.bindAll(this, 'openFileBrowser'); - config = Object.assign({}, baseConfig, config || {}); + config = _.extend({}, baseConfig, config || {}); this.wysiwygInstance = new WysiwygInstancePrototype(htmlId, config); this.wysiwygInstance.eventBus = this.eventBus = new window.varienEvents(); }, From beb1f0cd690209a7d71c01482c8627775944363e Mon Sep 17 00:00:00 2001 From: Dave Macaulay <dmacaulay@magento.com> Date: Tue, 18 Sep 2018 13:24:21 +0200 Subject: [PATCH 058/812] MC-4189: IE11 - PageBuilder Does Not Load - Update WeakMap polyfill to resolve stack memory errors in IE 11 --- lib/web/es6-collections.js | 273 +++++++------------------------------ 1 file changed, 46 insertions(+), 227 deletions(-) diff --git a/lib/web/es6-collections.js b/lib/web/es6-collections.js index 50ff560e53a8a..ed8e80c1fd07e 100644 --- a/lib/web/es6-collections.js +++ b/lib/web/es6-collections.js @@ -1,227 +1,46 @@ -(function (exports) {'use strict'; - //shared pointer - var i; - //shortcuts - var defineProperty = Object.defineProperty, is = function(a,b) { return isNaN(a)? isNaN(b): a === b; }; - - - //Polyfill global objects - if (typeof WeakMap == 'undefined') { - exports.WeakMap = createCollection({ - // WeakMap#delete(key:void*):boolean - 'delete': sharedDelete, - // WeakMap#clear(): - clear: sharedClear, - // WeakMap#get(key:void*):void* - get: sharedGet, - // WeakMap#has(key:void*):boolean - has: mapHas, - // WeakMap#set(key:void*, value:void*):void - set: sharedSet - }, true); - } - - if (typeof Map == 'undefined' || typeof ((new Map).values) !== 'function' || !(new Map).values().next) { - exports.Map = createCollection({ - // WeakMap#delete(key:void*):boolean - 'delete': sharedDelete, - //:was Map#get(key:void*[, d3fault:void*]):void* - // Map#has(key:void*):boolean - has: mapHas, - // Map#get(key:void*):boolean - get: sharedGet, - // Map#set(key:void*, value:void*):void - set: sharedSet, - // Map#keys(void):Iterator - keys: sharedKeys, - // Map#values(void):Iterator - values: sharedValues, - // Map#entries(void):Iterator - entries: mapEntries, - // Map#forEach(callback:Function, context:void*):void ==> callback.call(context, key, value, mapObject) === not in specs` - forEach: sharedForEach, - // Map#clear(): - clear: sharedClear - }); - } - - if (typeof Set == 'undefined' || typeof ((new Set).values) !== 'function' || !(new Set).values().next) { - exports.Set = createCollection({ - // Set#has(value:void*):boolean - has: setHas, - // Set#add(value:void*):boolean - add: sharedAdd, - // Set#delete(key:void*):boolean - 'delete': sharedDelete, - // Set#clear(): - clear: sharedClear, - // Set#keys(void):Iterator - keys: sharedValues, // specs actually say "the same function object as the initial value of the values property" - // Set#values(void):Iterator - values: sharedValues, - // Set#entries(void):Iterator - entries: setEntries, - // Set#forEach(callback:Function, context:void*):void ==> callback.call(context, value, index) === not in specs - forEach: sharedForEach - }); - } - - if (typeof WeakSet == 'undefined') { - exports.WeakSet = createCollection({ - // WeakSet#delete(key:void*):boolean - 'delete': sharedDelete, - // WeakSet#add(value:void*):boolean - add: sharedAdd, - // WeakSet#clear(): - clear: sharedClear, - // WeakSet#has(value:void*):boolean - has: setHas - }, true); - } - - - /** - * ES6 collection constructor - * @return {Function} a collection class - */ - function createCollection(proto, objectOnly){ - function Collection(a){ - if (!this || this.constructor !== Collection) return new Collection(a); - this._keys = []; - this._values = []; - this._itp = []; // iteration pointers - this.objectOnly = objectOnly; - - //parse initial iterable argument passed - if (a) init.call(this, a); - } - - //define size for non object-only collections - if (!objectOnly) { - defineProperty(proto, 'size', { - get: sharedSize - }); - } - - //set prototype - proto.constructor = Collection; - Collection.prototype = proto; - - return Collection; - } - - - /** parse initial iterable argument passed */ - function init(a){ - var i; - //init Set argument, like `[1,2,3,{}]` - if (this.add) - a.forEach(this.add, this); - //init Map argument like `[[1,2], [{}, 4]]` - else - a.forEach(function(a){this.set(a[0],a[1])}, this); - } - - - /** delete */ - function sharedDelete(key) { - if (this.has(key)) { - this._keys.splice(i, 1); - this._values.splice(i, 1); - // update iteration pointers - this._itp.forEach(function(p) { if (i < p[0]) p[0]--; }); - } - // Aurora here does it while Canary doesn't - return -1 < i; - }; - - function sharedGet(key) { - return this.has(key) ? this._values[i] : undefined; - } - - function has(list, key) { - if (this.objectOnly && key !== Object(key)) - throw new TypeError("Invalid value used as weak collection key"); - //NaN or 0 passed - if (key != key || key === 0) for (i = list.length; i-- && !is(list[i], key);){} - else i = list.indexOf(key); - return -1 < i; - } - - function setHas(value) { - return has.call(this, this._values, value); - } - - function mapHas(value) { - return has.call(this, this._keys, value); - } - - /** @chainable */ - function sharedSet(key, value) { - this.has(key) ? - this._values[i] = value - : - this._values[this._keys.push(key) - 1] = value - ; - return this; - } - - /** @chainable */ - function sharedAdd(value) { - if (!this.has(value)) this._values.push(value); - return this; - } - - function sharedClear() { - this._values.length = 0; - } - - /** keys, values, and iterate related methods */ - function sharedKeys() { - return sharedIterator(this._itp, this._keys); - } - - function sharedValues() { - return sharedIterator(this._itp, this._values); - } - - function mapEntries() { - return sharedIterator(this._itp, this._keys, this._values); - } - - function setEntries() { - return sharedIterator(this._itp, this._values, this._values); - } - - function sharedIterator(itp, array, array2) { - var p = [0], done = false; - itp.push(p); - return { - next: function() { - var v, k = p[0]; - if (!done && k < array.length) { - v = array2 ? [array[k], array2[k]]: array[k]; - p[0]++; - } else { - done = true; - itp.splice(itp.indexOf(p), 1); - } - return { done: done, value: v }; - } - }; - } - - function sharedSize() { - return this._values.length; - } - - function sharedForEach(callback, context) { - var it = this.entries(); - for (;;) { - var r = it.next(); - if (r.done) break; - callback.call(context, r.value[1], r.value[0], this); - } - } - -})(typeof exports != 'undefined' && typeof global != 'undefined' ? global : window ); \ No newline at end of file +/* + * Copyright 2012 The Polymer Authors. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +if (typeof WeakMap === 'undefined') { + (function() { + var defineProperty = Object.defineProperty; + var counter = Date.now() % 1e9; + + var WeakMap = function() { + this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__'); + }; + + WeakMap.prototype = { + set: function(key, value) { + var entry = key[this.name]; + if (entry && entry[0] === key) + entry[1] = value; + else + defineProperty(key, this.name, {value: [key, value], writable: true}); + return this; + }, + get: function(key) { + var entry; + return (entry = key[this.name]) && entry[0] === key ? + entry[1] : undefined; + }, + delete: function(key) { + var entry = key[this.name]; + if (!entry) return false; + var hasValue = entry[0] === key; + entry[0] = entry[1] = undefined; + return hasValue; + }, + has: function(key) { + var entry = key[this.name]; + if (!entry) return false; + return entry[0] === key; + } + }; + + window.WeakMap = WeakMap; + })(); +} \ No newline at end of file From 02ab61cc1a9ac377aca9d7b2d488fcd2a3858da6 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Sat, 15 Sep 2018 13:32:00 +0300 Subject: [PATCH 059/812] MAGETWO-59265: Import doesn't allow to set default value per store view (dropdown fields) - Changed logic of setting default value of attributes type "select" --- .../Model/Import/Product/Type/AbstractType.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php index afd018f077d20..8b04b7ec3532f 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php @@ -195,6 +195,8 @@ public function __construct( } /** + * Initialize template for error message. + * * @param array $templateCollection * @return $this */ @@ -377,6 +379,8 @@ public function retrieveAttributeFromCache($attributeCode) } /** + * Adding attribute option. + * * In case we've dynamically added new attribute option during import we need to add it to our cache * in order to keep it up to date. * @@ -508,8 +512,10 @@ public function isSuitable() } /** - * Prepare attributes values for save: exclude non-existent, static or with empty values attributes; - * set default values if needed + * Adding default attribute to product before save. + * + * Prepare attributes values for save: exclude non-existent, static or with empty values attributes, + * set default values if needed. * * @param array $rowData * @param bool $withDefaultValue @@ -539,7 +545,8 @@ public function prepareAttributesWithDefaultValueForSave(array $rowData, $withDe } } elseif (array_key_exists($attrCode, $rowData)) { $resultAttrs[$attrCode] = $rowData[$attrCode]; - } elseif ($withDefaultValue && null !== $attrParams['default_value']) { + } elseif ($withDefaultValue && null !== $attrParams['default_value'] + && 'select' == $attrParams['type'] && null === $rowData['_store']) { $resultAttrs[$attrCode] = $attrParams['default_value']; } } @@ -611,7 +618,8 @@ protected function getProductEntityLinkField() } /** - * Clean cached values + * Clean cached values. + * * @since 100.2.0 */ public function __destruct() From fc80a85de0d29219660c18c47d36866ab377fc97 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 18 Sep 2018 16:05:52 +0200 Subject: [PATCH 060/812] Removed temp debug logic --- lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php index 98e6c840ba682..a6ad10dded849 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryProcessor.php @@ -55,7 +55,6 @@ public function process( array $variableValues = null, string $operationName = null ) : array { - var_dump($this->exceptionFormatter->shouldShowDetail()); if (!$this->exceptionFormatter->shouldShowDetail()) { $this->queryComplexityLimiter->execute(); } From e5f051c51a6ebdcdf58137691b061548c321b362 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Thu, 13 Sep 2018 17:03:35 +0300 Subject: [PATCH 061/812] MAGETWO-91649: #13513: Magento ignore store-level url_key of child category in URL rewrite process for global scope - Fixed an issue with incorect url rewrites generation for children categories; - Modified unit tests for the new functionality; --- .../Category/ChildrenUrlRewriteGenerator.php | 35 ++++++++++++++----- .../ChildrenUrlRewriteGeneratorTest.php | 19 +++++++--- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php index 6aa33f37cd31f..f6049bbff02c4 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php @@ -10,7 +10,11 @@ use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator; use Magento\UrlRewrite\Model\MergeDataProviderFactory; use Magento\Framework\App\ObjectManager; +use Magento\Catalog\Api\CategoryRepositoryInterface; +/** + * Model for generate url rewrites for children categories + */ class ChildrenUrlRewriteGenerator { /** @@ -28,15 +32,22 @@ class ChildrenUrlRewriteGenerator */ private $mergeDataProviderPrototype; + /** + * @var CategoryRepositoryInterface + */ + private $categoryRepository; + /** * @param \Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider $childrenCategoriesProvider * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGeneratorFactory $categoryUrlRewriteGeneratorFactory * @param \Magento\UrlRewrite\Model\MergeDataProviderFactory|null $mergeDataProviderFactory + * @param CategoryRepositoryInterface|null $categoryRepository */ public function __construct( ChildrenCategoriesProvider $childrenCategoriesProvider, CategoryUrlRewriteGeneratorFactory $categoryUrlRewriteGeneratorFactory, - MergeDataProviderFactory $mergeDataProviderFactory = null + MergeDataProviderFactory $mergeDataProviderFactory = null, + CategoryRepositoryInterface $categoryRepository = null ) { $this->childrenCategoriesProvider = $childrenCategoriesProvider; $this->categoryUrlRewriteGeneratorFactory = $categoryUrlRewriteGeneratorFactory; @@ -44,6 +55,8 @@ public function __construct( $mergeDataProviderFactory = ObjectManager::getInstance()->get(MergeDataProviderFactory::class); } $this->mergeDataProviderPrototype = $mergeDataProviderFactory->create(); + $this->categoryRepository = $categoryRepository + ?: ObjectManager::getInstance()->get(CategoryRepositoryInterface::class); } /** @@ -53,18 +66,22 @@ public function __construct( * @param \Magento\Catalog\Model\Category $category * @param int|null $rootCategoryId * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] + * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function generate($storeId, Category $category, $rootCategoryId = null) { $mergeDataProvider = clone $this->mergeDataProviderPrototype; - foreach ($this->childrenCategoriesProvider->getChildren($category, true) as $childCategory) { - $childCategory->setStoreId($storeId); - $childCategory->setData('save_rewrites_history', $category->getData('save_rewrites_history')); - /** @var CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator */ - $categoryUrlRewriteGenerator = $this->categoryUrlRewriteGeneratorFactory->create(); - $mergeDataProvider->merge( - $categoryUrlRewriteGenerator->generate($childCategory, false, $rootCategoryId) - ); + if ($childrenIds = $this->childrenCategoriesProvider->getChildrenIds($category, true)) { + foreach ($childrenIds as $childId) { + /** @var Category $childCategory */ + $childCategory = $this->categoryRepository->get($childId, $storeId); + $childCategory->setData('save_rewrites_history', $category->getData('save_rewrites_history')); + /** @var CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator */ + $categoryUrlRewriteGenerator = $this->categoryUrlRewriteGeneratorFactory->create(); + $mergeDataProvider->merge( + $categoryUrlRewriteGenerator->generate($childCategory, false, $rootCategoryId) + ); + } } return $mergeDataProvider->getData(); diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/ChildrenUrlRewriteGeneratorTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/ChildrenUrlRewriteGeneratorTest.php index 3f641256b1259..f8422c7c05fa6 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/ChildrenUrlRewriteGeneratorTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/ChildrenUrlRewriteGeneratorTest.php @@ -31,6 +31,9 @@ class ChildrenUrlRewriteGeneratorTest extends \PHPUnit\Framework\TestCase /** @var \PHPUnit_Framework_MockObject_MockObject */ private $serializerMock; + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $categoryRepository; + protected function setUp() { $this->serializerMock = $this->getMockBuilder(Json::class) @@ -47,6 +50,9 @@ protected function setUp() $this->categoryUrlRewriteGenerator = $this->getMockBuilder( \Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator::class )->disableOriginalConstructor()->getMock(); + $this->categoryRepository = $this->getMockBuilder( + \Magento\Catalog\Model\CategoryRepository::class + )->disableOriginalConstructor()->getMock(); $mergeDataProviderFactory = $this->createPartialMock( \Magento\UrlRewrite\Model\MergeDataProviderFactory::class, ['create'] @@ -59,14 +65,15 @@ protected function setUp() [ 'childrenCategoriesProvider' => $this->childrenCategoriesProvider, 'categoryUrlRewriteGeneratorFactory' => $this->categoryUrlRewriteGeneratorFactory, - 'mergeDataProviderFactory' => $mergeDataProviderFactory + 'mergeDataProviderFactory' => $mergeDataProviderFactory, + 'categoryRepository' => $this->categoryRepository ] ); } public function testNoChildrenCategories() { - $this->childrenCategoriesProvider->expects($this->once())->method('getChildren')->with($this->category, true) + $this->childrenCategoriesProvider->expects($this->once())->method('getChildrenIds')->with($this->category, true) ->will($this->returnValue([])); $this->assertEquals([], $this->childrenUrlRewriteGenerator->generate('store_id', $this->category)); @@ -76,14 +83,16 @@ public function testGenerate() { $storeId = 'store_id'; $saveRewritesHistory = 'flag'; + $childId = 2; $childCategory = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) ->disableOriginalConstructor()->getMock(); - $childCategory->expects($this->once())->method('setStoreId')->with($storeId); $childCategory->expects($this->once())->method('setData') ->with('save_rewrites_history', $saveRewritesHistory); - $this->childrenCategoriesProvider->expects($this->once())->method('getChildren')->with($this->category, true) - ->will($this->returnValue([$childCategory])); + $this->childrenCategoriesProvider->expects($this->once())->method('getChildrenIds')->with($this->category, true) + ->will($this->returnValue([$childId])); + $this->categoryRepository->expects($this->once())->method('get') + ->with($childId, $storeId)->willReturn($childCategory); $this->category->expects($this->any())->method('getData')->with('save_rewrites_history') ->will($this->returnValue($saveRewritesHistory)); $this->categoryUrlRewriteGeneratorFactory->expects($this->once())->method('create') From 1b9ae1174da8a34ac898ea2bc69cfa39f75eb252 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 18 Sep 2018 15:32:37 +0300 Subject: [PATCH 062/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fixes according to code review. --- .../Block/Product/ProductList/Toolbar.php | 2 ++ .../Framework}/App/Action/ContextPlugin.php | 28 ++++++++----------- .../Magento/Catalog/etc/adminhtml/system.xml | 3 +- app/code/Magento/Catalog/etc/frontend/di.xml | 2 +- 4 files changed, 16 insertions(+), 19 deletions(-) rename app/code/Magento/Catalog/{Model => Plugin/Framework}/App/Action/ContextPlugin.php (60%) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index 3e3f86cd7de01..12c691d1365c3 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -150,6 +150,8 @@ class Toolbar extends \Magento\Framework\View\Element\Template * @param \Magento\Framework\App\Http\Context|null $httpContext * @param \Magento\Framework\Data\Form\FormKey|null $formKey * @param array $data + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, diff --git a/app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php b/app/code/Magento/Catalog/Plugin/Framework/App/Action/ContextPlugin.php similarity index 60% rename from app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php rename to app/code/Magento/Catalog/Plugin/Framework/App/Action/ContextPlugin.php index c5ed81540e29e..6add542b15554 100644 --- a/app/code/Magento/Catalog/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Catalog/Plugin/Framework/App/Action/ContextPlugin.php @@ -6,7 +6,7 @@ declare(strict_types=1); -namespace Magento\Catalog\Model\App\Action; +namespace Magento\Catalog\Plugin\Framework\App\Action; use Magento\Catalog\Model\Product\ProductList\Toolbar as ToolbarModel; use Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer; @@ -56,21 +56,17 @@ public function __construct( public function beforeDispatch() { if ($this->toolbarMemorizer->isMemorizingAllowed()) { - $order = $this->catalogSession->getData(ToolbarModel::ORDER_PARAM_NAME); - if ($order) { - $this->httpContext->setValue(ToolbarModel::ORDER_PARAM_NAME, $order, false); - } - $direction = $this->catalogSession->getData(ToolbarModel::DIRECTION_PARAM_NAME); - if ($direction) { - $this->httpContext->setValue(ToolbarModel::DIRECTION_PARAM_NAME, $direction, false); - } - $mode = $this->catalogSession->getData(ToolbarModel::MODE_PARAM_NAME); - if ($mode) { - $this->httpContext->setValue(ToolbarModel::MODE_PARAM_NAME, $mode, false); - } - $limit = $this->catalogSession->getData(ToolbarModel::LIMIT_PARAM_NAME); - if ($limit) { - $this->httpContext->setValue(ToolbarModel::LIMIT_PARAM_NAME, $limit, false); + $params = [ + ToolbarModel::ORDER_PARAM_NAME, + ToolbarModel::DIRECTION_PARAM_NAME, + ToolbarModel::MODE_PARAM_NAME, + ToolbarModel::LIMIT_PARAM_NAME + ]; + foreach ($params as $param) { + $paramValue = $this->catalogSession->getData($param); + if ($paramValue) { + $this->httpContext->setValue($param, $paramValue, false); + } } } } diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml index be35ae2e5549d..adfe4c735201c 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/system.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml @@ -94,8 +94,7 @@ </field> <field id="remember_pagination" translate="label comment" type="select" sortOrder="7" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Remember Category Pagination</label> - <comment>Note that SEO and performance experience may be negative by this feature enabled. - Also it will increase cache storage consumption.</comment> + <comment>Changing may affect SEO and cache storage consumption.</comment> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> </group> diff --git a/app/code/Magento/Catalog/etc/frontend/di.xml b/app/code/Magento/Catalog/etc/frontend/di.xml index a1520b66e83dc..ee9c5b29da894 100644 --- a/app/code/Magento/Catalog/etc/frontend/di.xml +++ b/app/code/Magento/Catalog/etc/frontend/di.xml @@ -118,6 +118,6 @@ </type> <type name="Magento\Framework\App\Action\AbstractAction"> <plugin name="catalog_app_action_dispatch_controller_context_plugin" - type="Magento\Catalog\Model\App\Action\ContextPlugin" /> + type="Magento\Catalog\Plugin\Framework\App\Action\ContextPlugin" /> </type> </config> From 1992a368332102563331372d2267f633e3752940 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 18 Sep 2018 17:32:06 +0200 Subject: [PATCH 063/812] Travis api-functional testsuite check --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index cc730ca5a2cd4..e909bb1980752 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,7 @@ env: - TEST_SUITE=integration INTEGRATION_INDEX=2 - TEST_SUITE=integration INTEGRATION_INDEX=3 - TEST_SUITE=functional + - TEST_SUITE=api-functional matrix: exclude: - php: 7.1 From 0c7edc5a71a02bcc6df929ac0d0f7518b18a376b Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Tue, 18 Sep 2018 20:35:30 +0400 Subject: [PATCH 064/812] MAGETWO-91617: Ordered Products Report Error for restricted scope admin - Add some helpers for automated test --- .../ActionGroup/AdminProductActionGroup.xml | 17 +++++++- ...omerWithWebsiteAndStoreViewActionGroup.xml | 43 +++++++++++++++++++ .../AdminDeleteCustomerActionGroup.xml | 23 ++++++++++ .../Customer/Test/Mftf/Data/AddressData.xml | 1 + ...AdminCustomerAccountInformationSection.xml | 1 + .../Section/AdminCustomerAddressesSection.xml | 24 +++++++++++ .../AdminCustomerGridMainActionsSection.xml | 2 + .../AdminReviewOrderActionGroup.xml | 24 +++++++++++ .../Mftf/Section/OrderedProductsSection.xml | 17 ++++++++ .../ActionGroup/AdminOrderActionGroup.xml | 24 +++++++++++ .../AdminInvoicePaymentShippingSection.xml | 2 + .../AdminOrderStoreScopeTreeSection.xml | 1 + .../Mftf/Section/AdminOrdersGridSection.xml | 2 + .../Test/Mftf/Section/OrdersGridSection.xml | 3 +- .../Store/Test/Mftf/Data/StoreData.xml | 12 ++++++ .../AdminCreateUserActionGroup.xml | 23 ++++++++++ .../AdminDeleteCreatedUserActionGroup.xml | 23 ++++++++++ 17 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCreateCustomerWithWebsiteAndStoreViewActionGroup.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesSection.xml create mode 100644 app/code/Magento/Reports/Test/Mftf/ActionGroup/AdminReviewOrderActionGroup.xml create mode 100644 app/code/Magento/Reports/Test/Mftf/Section/OrderedProductsSection.xml create mode 100644 app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteCreatedUserActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml index 9f8d827b20849..91141a573cf5b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml @@ -276,5 +276,20 @@ <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="acceptStoreSwitchingMessage"/> <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> - + <actionGroup name="CreatedProductConnectToWebsite"> + <arguments> + <argument name="website"/> + <argument name="product"/> + </arguments> + <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="navigateToProductPage"/> + <waitForPageLoad stepKey="waitForProductsList"/> + <click stepKey="openProduct" selector="{{AdminProductGridActionSection.productName(product.name)}}"/> + <waitForPageLoad stepKey="waitForProductPage"/> + <scrollTo selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="ScrollToWebsites"/> + <click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="openWebsitesList"/> + <waitForPageLoad stepKey="waitForWebsitesList"/> + <click selector="{{ProductInWebsitesSection.website(website.name)}}" stepKey="SelectWebsite"/> + <click selector="{{AdminProductFormAdvancedPricingSection.save}}" stepKey="clickSaveProduct"/> + <waitForPageLoad stepKey="waitForSave"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCreateCustomerWithWebsiteAndStoreViewActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCreateCustomerWithWebsiteAndStoreViewActionGroup.xml new file mode 100644 index 0000000000000..0071acf2ef1e0 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCreateCustomerWithWebsiteAndStoreViewActionGroup.xml @@ -0,0 +1,43 @@ +<?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="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminCreateCustomerWithWebsiteAndStoreViewActionGroup"> + <arguments> + <argument name="customerData"/> + <argument name="address"/> + <argument name="website" type="string"/> + <argument name="storeView" type="string"/> + </arguments> + <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersPage"/> + <click stepKey="addNewCustomer" selector="{{AdminCustomerGridMainActionsSection.addNewCustomer}}"/> + <selectOption stepKey="selectWebSite" selector="{{AdminCustomerAccountInformationSection.associateToWebsite}}" userInput="{{website}}"/> + <fillField stepKey="FillFirstName" selector="{{AdminCustomerAccountInformationSection.firstName}}" userInput="{{customerData.firstname}}"/> + <fillField stepKey="FillLastName" selector="{{AdminCustomerAccountInformationSection.lastName}}" userInput="{{customerData.lastname}}"/> + <fillField stepKey="FillEmail" selector="{{AdminCustomerAccountInformationSection.email}}" userInput="{{customerData.email}}"/> + <selectOption stepKey="selectStoreView" selector="{{AdminCustomerAccountInformationSection.storeView}}" userInput="{{storeView}}"/> + <scrollToTopOfPage stepKey="scrollToTopOfThePage"/> + <click stepKey="goToAddresses" selector="{{AdminCustomerAccountInformationSection.addressesButton}}"/> + <waitForPageLoad stepKey="waitForAddresses"/> + <click stepKey="clickOnAddNewAddress" selector="{{AdminCustomerAddressesSection.addNewAddress}}"/> + <waitForPageLoad stepKey="waitForAddressFields"/> + <click stepKey="thickBillingAddress" selector="{{AdminCustomerAddressesSection.defaultBillingAddress}}"/> + <click stepKey="thickShippingAddress" selector="{{AdminCustomerAddressesSection.defaultShippingAddress}}"/> + <fillField stepKey="fillFirstNameForAddress" selector="{{AdminCustomerAddressesSection.firstNameForAddress}}" userInput="{{address.firstname}}"/> + <fillField stepKey="fillLastNameForAddress" selector="{{AdminCustomerAddressesSection.lastNameForAddress}}" userInput="{{address.lastname}}"/> + <fillField stepKey="fillStreetAddress" selector="{{AdminCustomerAddressesSection.streetAddress}}" userInput="{{address.street[0]}}"/> + <fillField stepKey="fillCity" selector="{{AdminCustomerAddressesSection.city}}" userInput="{{address.city}}"/> + <selectOption stepKey="selectCountry" selector="{{AdminCustomerAddressesSection.country}}" userInput="{{address.country}}"/> + <selectOption stepKey="selectState" selector="{{AdminCustomerAddressesSection.state}}" userInput="{{address.state}}"/> + <fillField stepKey="fillZip" selector="{{AdminCustomerAddressesSection.zip}}" userInput="{{address.postcode}}"/> + <fillField stepKey="fillPhoneNumber" selector="{{AdminCustomerAddressesSection.phoneNumber}}" userInput="{{address.telephone}}"/> + <click stepKey="save" selector="{{AdminCustomerAccountInformationSection.saveCustomer}}"/> + <waitForPageLoad stepKey="waitForCustomersPage"/> + <see stepKey="seeSuccessMessage" userInput="You saved the customer."/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.xml new file mode 100644 index 0000000000000..68f6b49e80996 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerActionGroup.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="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminDeleteCustomerActionGroup"> + <arguments> + <argument name="customerEmail"/> + </arguments> + <amOnPage url="{{AdminCustomerPage.url}}" stepKey="navigateToCustomersPage"/> + <click stepKey="chooseCustomer" selector="{{AdminCustomerGridMainActionsSection.customerCheckbox(customerEmail)}}"/> + <click stepKey="openActions" selector="{{AdminCustomerGridMainActionsSection.actions}}"/> + <waitForPageLoad stepKey="waitActions"/> + <click stepKey="delete" selector="{{AdminCustomerGridMainActionsSection.delete}}"/> + <waitForPageLoad stepKey="waitForConfirmationAlert"/> + <click stepKey="accept" selector="{{AdminCustomerGridMainActionsSection.ok}}"/> + <see stepKey="seeSuccessMessage" userInput="were deleted."/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml index d090620145105..033add209a4c2 100755 --- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml @@ -65,6 +65,7 @@ <data key="default_billing">Yes</data> <data key="default_shipping">Yes</data> <requiredEntity type="region">RegionNY</requiredEntity> + <data key="country">United States</data> </entity> <entity name="US_Address_CA" type="address"> <data key="firstname">John</data> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml index 32746a66621eb..8510fd385f92b 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml @@ -11,6 +11,7 @@ <section name="AdminCustomerAccountInformationSection"> <element name="accountInformationTitle" type="text" selector=".admin__page-nav-title"/> <element name="accountInformationButton" type="text" selector="//a/span[text()='Account Information']"/> + <element name="addressesButton" type="select" selector="//a//span[contains(text(), 'Addresses')]"/> <element name="firstName" type="input" selector="input[name='customer[firstname]']"/> <element name="lastName" type="input" selector="input[name='customer[lastname]']"/> <element name="email" type="input" selector="input[name='customer[email]']"/> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesSection.xml new file mode 100644 index 0000000000000..175c7ab573d37 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesSection.xml @@ -0,0 +1,24 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminCustomerAddressesSection"> + <element name="addNewAddress" type="button" selector="//span[text()='Add New Addresses']"/> + <element name="defaultBillingAddress" type="button" selector="//label[text()='Default Billing Address']"/> + <element name="defaultShippingAddress" type="button" selector="//label[text()='Default Shipping Address']"/> + <element name="firstNameForAddress" type="button" selector="//input[contains(@name, 'address')][contains(@name, 'firstname')]"/> + <element name="lastNameForAddress" type="button" selector="//input[contains(@name, 'address')][contains(@name, 'lastname')]"/> + <element name="streetAddress" type="button" selector="//input[contains(@name, 'street')]"/> + <element name="city" type="input" selector="//input[contains(@name, 'city')]"/> + <element name="country" type="select" selector="//select[contains(@name, 'country_id')]"/> + <element name="state" type="select" selector="//select[contains(@name, 'address[new_0][region_id]')]"/> + <element name="zip" type="input" selector="//input[contains(@name, 'postcode')]"/> + <element name="phoneNumber" type="input" selector="//input[contains(@name, 'telephone')]"/> + </section> +</sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGridMainActionsSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGridMainActionsSection.xml index 1f0c4b4998a9f..d644b581088bc 100755 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGridMainActionsSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGridMainActionsSection.xml @@ -13,5 +13,7 @@ <element name="multicheck" type="checkbox" selector="#container>div>div.admin__data-grid-wrap>table>thead>tr>th.data-grid-multicheck-cell>div>label"/> <element name="delete" type="button" selector="//*[contains(@class, 'admin__data-grid-header')]//span[contains(@class,'action-menu-item') and text()='Delete']"/> <element name="actions" type="text" selector=".action-select"/> + <element name="customerCheckbox" type="button" selector="//*[contains(text(),'{{arg}}')]/parent::td/preceding-sibling::td/label[@class='data-grid-checkbox-cell-inner']//input" parameterized="true"/> + <element name="ok" type="button" selector="//button[@data-role='action']//span[text()='OK']"/> </section> </sections> diff --git a/app/code/Magento/Reports/Test/Mftf/ActionGroup/AdminReviewOrderActionGroup.xml b/app/code/Magento/Reports/Test/Mftf/ActionGroup/AdminReviewOrderActionGroup.xml new file mode 100644 index 0000000000000..003a5e6655f34 --- /dev/null +++ b/app/code/Magento/Reports/Test/Mftf/ActionGroup/AdminReviewOrderActionGroup.xml @@ -0,0 +1,24 @@ +<?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="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminReviewOrderActionGroup"> + <arguments> + <argument name="productName" type="string"/> + </arguments> + <click stepKey="openReports" selector="{{OrderedProductsSection.reports}}"/> + <waitForPageLoad stepKey="waitForReports" time="5"/> + <click stepKey="openOrdered" selector="{{OrderedProductsSection.ordered}}"/> + <waitForPageLoad stepKey="waitForOrdersPage" time="5"/> + <click stepKey="refresh" selector="{{OrderedProductsSection.refresh}}"/> + <waitForPageLoad stepKey="waitForOrderList" time="5"/> + <scrollTo stepKey="scrollTo" selector="{{OrderedProductsSection.total}}"/> + <see stepKey="seeOrder" userInput="{{productName}}"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Reports/Test/Mftf/Section/OrderedProductsSection.xml b/app/code/Magento/Reports/Test/Mftf/Section/OrderedProductsSection.xml new file mode 100644 index 0000000000000..89e8497dddcea --- /dev/null +++ b/app/code/Magento/Reports/Test/Mftf/Section/OrderedProductsSection.xml @@ -0,0 +1,17 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="OrderedProductsSection"> + <element name="reports" type="button" selector="//li[@data-ui-id='menu-magento-reports-report']"/> + <element name="ordered" type="button" selector="//li[@data-ui-id='menu-magento-reports-report-products-sold']"/> + <element name="refresh" type="button" selector="//button[@title='Refresh']" timeout="30"/> + <element name="total" type="text" selector="//tfoot//th[contains(text(), 'Total')]"/> + </section> +</sections> \ No newline at end of file diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml index c82623632d782..ffa6a2a5f2d99 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml @@ -268,4 +268,28 @@ <see selector="{{AdminMessagesSection.success}}" userInput="You canceled the order." stepKey="seeCancelSuccessMessage"/> <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Canceled" stepKey="seeOrderStatusCanceled"/> </actionGroup> + + <actionGroup name="CreateOrderInStoreActionGroup"> + <arguments> + <argument name="product"/> + <argument name="customer"/> + <argument name="storeView"/> + </arguments> + <amOnPage stepKey="navigateToNewOrderPage" url="{{AdminOrderCreatePage.url}}"/> + <click stepKey="chooseCustomer" selector="{{AdminOrdersGridSection.customerInOrdersSection(customer.firstname)}}"/> + <waitForPageLoad stepKey="waitForStoresPageOpened"/> + <click stepKey="chooseStore" selector="{{AdminOrderStoreScopeTreeSection.storeForOrder(storeView.name)}}"/> + <scrollToTopOfPage stepKey="scrollToTop"/> + <click selector="{{OrdersGridSection.addProducts}}" stepKey="clickOnAddProducts"/> + <waitForPageLoad stepKey="waitForProductsListForOrder"/> + <click selector="{{AdminOrdersGridSection.productForOrder(product.sku)}}" stepKey="chooseTheProduct"/> + <click selector="{{AdminOrderFormItemsSection.addSelected}}" stepKey="addSelectedProductToOrder"/> + <waitForPageLoad stepKey="waitForProductAddedInOrder"/> + <click selector="{{AdminInvoicePaymentShippingSection.getShippingMethodAndRates}}" stepKey="openShippingMethod"/> + <waitForPageLoad stepKey="waitForShippingMethods"/> + <click selector="{{AdminInvoicePaymentShippingSection.shippingMethod}}" stepKey="chooseShippingMethod"/> + <waitForPageLoad stepKey="waitForShippingMethodsThickened"/> + <click selector="{{OrdersGridSection.submitOrder}}" stepKey="submitOrder"/> + <see stepKey="seeSuccessMessageForOrder" userInput="You created the order."/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml index 918a8e814b555..8d7c64733972e 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml @@ -15,5 +15,7 @@ <element name="ShippingMethod" type="text" selector=".order-shipping-address .shipping-description-title"/> <element name="ShippingPrice" type="text" selector=".order-shipping-address .shipping-description-content .price"/> <element name="CreateShipment" type="checkbox" selector=".order-shipping-address input[name='invoice[do_shipment]']"/> + <element name="getShippingMethodAndRates" type="button" selector="//span[text()='Get shipping methods and rates']"/> + <element name="shippingMethod" type="button" selector="//label[contains(text(), 'Fixed')]"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStoreScopeTreeSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStoreScopeTreeSection.xml index 050e1ba8b2df4..cbe17499319f9 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStoreScopeTreeSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStoreScopeTreeSection.xml @@ -11,5 +11,6 @@ <section name="AdminOrderStoreScopeTreeSection"> <element name="storeTree" type="text" selector="div.tree-store-scope"/> <element name="storeOption" type="radio" selector="//div[contains(@class, 'tree-store-scope')]//label[contains(text(), '{{name}}')]/preceding-sibling::input" parameterized="true" timeout="30"/> + <element name="storeForOrder" type="radio" selector="//div[contains(@class, 'tree-store-scope')]//label[contains(text(), '{{arg}}')]" parameterized="true" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml index 7ece18fb863b7..53a6cbffcdac6 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml @@ -29,5 +29,7 @@ <element name="viewBookmark" type="button" selector="//div[contains(@class, 'admin__data-grid-action-bookmarks')]/ul/li/div/a[text() = '{{label}}']" parameterized="true" timeout="30"/> <element name="columnsDropdown" type="button" selector="div.admin__data-grid-action-columns button" timeout="30"/> <element name="viewColumnCheckbox" type="checkbox" selector="//div[contains(@class,'admin__data-grid-action-columns')]//div[contains(@class, 'admin__field-option')]//label[text() = '{{column}}']/preceding-sibling::input" parameterized="true"/> + <element name="customerInOrdersSection" type="button" selector="(//td[contains(text(),'{{customer}}')])[1]" parameterized="true"/> + <element name="productForOrder" type="button" selector="//td[contains(text(),'{{var}}')]" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/OrdersGridSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/OrdersGridSection.xml index 8d99bf4872d0a..717022322698f 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/OrdersGridSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/OrdersGridSection.xml @@ -18,7 +18,7 @@ <element name="createNewOrder" type="button" selector="button[title='Create New Order'"/> <element name="website" type="radio" selector="//label[contains(text(), '{{arg}}')]" parameterized="true"/> - <element name="addProducts" type="button" selector="//span[text()='Add Products']"/> + <element name="addProducts" type="button" selector="#add_products"/> <element name="selectProduct" type="checkbox" selector="//td[contains(text(), '{{arg}}')]/following-sibling::td[contains(@class, 'col-select col-in_products')]" parameterized="true"/> <element name="setQuantity" type="checkbox" selector="//td[contains(text(), '{{arg}}')]/following-sibling::td[contains(@class, 'col-qty')]/input" parameterized="true"/> <element name="addProductsToOrder" type="button" selector="//span[text()='Add Selected Product(s) to Order']"/> @@ -29,5 +29,6 @@ <element name="productPrice" type="text" selector="//span[text()='{{arg}}']/parent::td/following-sibling::td[@class='col-price col-row-subtotal']/span" parameterized="true"/> <element name="removeItems" type="select" selector="//span[text()='{{arg}}']/parent::td/following-sibling::td/select[@class='admin__control-select']" parameterized="true"/> <element name="applyCoupon" type="input" selector="#coupons:code"/> + <element name="submitOrder" type="button" selector="#submit_order_top_button"/> </section> </sections> diff --git a/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml b/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml index 2bff20e05435a..b0f04dbe703a9 100644 --- a/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml +++ b/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml @@ -49,4 +49,16 @@ <data key="store_type">store</data> <requiredEntity type="storeGroup">customStoreGroup</requiredEntity> </entity> + <entity name="NewStoreData" type="store"> + <data key="name" unique="suffix">Store</data> + <data key="code" unique="suffix">StoreCode</data> + </entity> + <entity name="NewWebSiteData" type="webSite"> + <data key="name" unique="suffix">WebSite</data> + <data key="code" unique="suffix">WebSiteCode</data> + </entity> + <entity name="NewStoreViewData"> + <data key="name" unique="suffix">StoreView</data> + <data key="code" unique="suffix">StoreViewCode</data> + </entity> </entities> diff --git a/app/code/Magento/User/Test/Mftf/ActionGroup/AdminCreateUserActionGroup.xml b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminCreateUserActionGroup.xml index de887d2de6704..9a0fa4a205799 100644 --- a/app/code/Magento/User/Test/Mftf/ActionGroup/AdminCreateUserActionGroup.xml +++ b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminCreateUserActionGroup.xml @@ -31,4 +31,27 @@ <waitForPageLoad stepKey="waitForPageLoad2" /> <see userInput="You saved the user." stepKey="seeSuccessMessage" /> </actionGroup> + + <!--Create new user with role--> + <actionGroup name="AdminCreateUserWithRoleActionGroup"> + <arguments> + <argument name="role"/> + <argument name="user" defaultValue="newAdmin"/> + </arguments> + <amOnPage url="{{AdminEditUserPage.url}}" stepKey="navigateToNewUser"/> + <waitForPageLoad stepKey="waitForUsersPage" /> + <fillField selector="{{AdminCreateUserSection.usernameTextField}}" userInput="{{user.username}}" stepKey="enterUserName" /> + <fillField selector="{{AdminCreateUserSection.firstNameTextField}}" userInput="{{user.firstName}}" stepKey="enterFirstName" /> + <fillField selector="{{AdminCreateUserSection.lastNameTextField}}" userInput="{{user.lastName}}" stepKey="enterLastName" /> + <fillField selector="{{AdminCreateUserSection.emailTextField}}" userInput="{{user.username}}@magento.com" stepKey="enterEmail" /> + <fillField selector="{{AdminCreateUserSection.passwordTextField}}" userInput="{{user.password}}" stepKey="enterPassword" /> + <fillField selector="{{AdminCreateUserSection.pwConfirmationTextField}}" userInput="{{user.password}}" stepKey="confirmPassword" /> + <fillField selector="{{AdminCreateUserSection.currentPasswordField}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}" stepKey="enterCurrentPassword" /> + <scrollToTopOfPage stepKey="scrollToTopOfPage" /> + <click stepKey="clickUserRole" selector="{{AdminCreateUserSection.userRoleTab}}"/> + <click stepKey="chooseRole" selector="{{AdminStoreSection.createdRoleInUserPage(role.name)}}"/> + <click selector="{{AdminCreateUserSection.saveButton}}" stepKey="clickSaveUser" /> + <waitForPageLoad stepKey="waitForSaveTheUser" /> + <see userInput="You saved the user." stepKey="seeSuccessMessage" /> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteCreatedUserActionGroup.xml b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteCreatedUserActionGroup.xml new file mode 100644 index 0000000000000..7f1ed3be1ca57 --- /dev/null +++ b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteCreatedUserActionGroup.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="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminDeleteCreatedUserActionGroup"> + <arguments> + <argument name="user"/> + </arguments> + <amOnPage stepKey="amOnAdminUsersPage" url="{{AdminUsersPage.url}}"/> + <click stepKey="openTheUser" selector="{{AdminDeleteUserSection.role(user.username)}}"/> + <fillField stepKey="TypeCurrentPassword" selector="{{AdminDeleteUserSection.password}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> + <scrollToTopOfPage stepKey="scrollToTop"/> + <click stepKey="clickToDeleteUser" selector="{{AdminDeleteUserSection.delete}}"/> + <waitForPageLoad stepKey="waitForConfirmationPopup"/> + <click stepKey="clickToConfirm" selector="{{AdminDeleteUserSection.confirm}}"/> + <see stepKey="seeDeleteMessageForUser" userInput="You deleted the user."/> + </actionGroup> +</actionGroups> From a6369144904e0503e21d80ef96e14396c2a3308f Mon Sep 17 00:00:00 2001 From: eugene-shab <dev.eugene.shab@gmail.com> Date: Tue, 18 Sep 2018 23:23:10 +0300 Subject: [PATCH 065/812] Fixed tests --- .../testsuite/Magento/GraphQl/Catalog/CategoryTest.php | 6 +++--- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php index 8841fab75790c..5f0be1bdb8a86 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php @@ -141,7 +141,7 @@ public function testCategoryProducts() available_sort_by level } - image + image { url, path } image_label meta_description meta_keyword @@ -225,13 +225,13 @@ public function testCategoryProducts() } short_description sku - small_image + small_image { url, path } small_image_label special_from_date special_price special_to_date swatch_image - thumbnail + thumbnail { url, path } thumbnail_label tier_price tier_prices { 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 34cebde64d03a..fdf1bfc35408b 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -53,7 +53,7 @@ public function testQueryAllFieldsSimpleProduct() available_sort_by level } - image + image { url, path } image_label meta_description meta_keyword @@ -205,13 +205,13 @@ public function testQueryAllFieldsSimpleProduct() } short_description sku - small_image + small_image { url, path } small_image_label special_from_date special_price special_to_date swatch_image - thumbnail + thumbnail { url, path } thumbnail_label tier_price tier_prices From 96092708fc5156ec967b3aa5d1704b86fcd65611 Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Tue, 18 Sep 2018 15:41:25 -0500 Subject: [PATCH 066/812] MAGETWO-94308: User can place order with amount less than "minimum order amount" via Checkout with multiple address flow. - Extract config value to variable to resolve code style error --- .../Multishipping/Model/Checkout/Type/Multishipping.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php index a30acdc3943ee..d1df064f57140 100644 --- a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php +++ b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php @@ -904,10 +904,12 @@ public function validateMinimumAmount() \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); - if ($this->_scopeConfig->isSetFlag( + $minimumOrderMultiFlag = $this->_scopeConfig->isSetFlag( 'sales/minimum_order/multi_address', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE) - ) { + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); + + if ($minimumOrderMultiFlag) { $result = !($minimumOrderActive && !$this->getQuote()->validateMinimumAmount()); } else { $result = !($minimumOrderActive && !$this->validateMinimumAmountForAddressItems()); From b48171bfa9c5fdb5ce1101dff67b4e3e0e5189ff Mon Sep 17 00:00:00 2001 From: Aleksey Tsoy <aleksey_tsoy@epam.com> Date: Wed, 19 Sep 2018 13:48:06 +0600 Subject: [PATCH 067/812] MAGETWO-71022: After return is complete in Admin, 'remaining quantity' in customer account shows incorrect value - Added automated test --- .../Mftf/ActionGroup/AdminInvoiceActionGroup.xml | 12 ++++++++++++ .../Mftf/ActionGroup/AdminShipmentActionGroup.xml | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml index 15aff7c751a11..905cb08a401e1 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml @@ -38,4 +38,16 @@ </arguments> <see selector="{{AdminInvoiceItemsSection.skuColumn}}" userInput="{{product.sku}}" stepKey="seeProductSkuInGrid"/> </actionGroup> + + <actionGroup name="goToInvoiceIntoOrder"> + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceAction"/> + <seeInCurrentUrl url="{{AdminInvoiceNewPage.url}}" stepKey="seeOrderInvoiceUrl"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seePageNameNewInvoicePage"/> + </actionGroup> + + <actionGroup name="submitInvoiceIntoOrder"> + <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="clickSubmitInvoice"/> + <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}" stepKey="seeViewOrderPageInvoice"/> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeInvoiceCreateSuccess"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml index 85430aeaa4168..3d70a742b13eb 100644 --- a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml +++ b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml @@ -35,4 +35,16 @@ </arguments> <see selector="{{AdminShipmentItemsSection.skuColumn}}" userInput="{{product.sku}}" stepKey="seeProductSkuInGrid"/> </actionGroup> + + <actionGroup name="goToShipmentIntoOrder"> + <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShipAction"/> + <seeInCurrentUrl url="{{AdminShipmentNewPage.url}}" stepKey="seeOrderShipmentUrl"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Shipment" stepKey="seePageNameNewInvoicePage"/> + </actionGroup> + + <actionGroup name="submitShipmentIntoOrder"> + <click selector="{{AdminShipmentMainActionsSection.submitShipment}}" stepKey="clickSubmitShipment"/> + <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}" stepKey="seeViewOrderPageShipping"/> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The shipment has been created." stepKey="seeShipmentCreateSuccess"/> + </actionGroup> </actionGroups> \ No newline at end of file From 78327c1ab246fc20ed84ee54ed67e2d97a1c5131 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Wed, 19 Sep 2018 14:06:15 +0300 Subject: [PATCH 068/812] MAGETWO-91657: Advanced pricing the bulk discounts by percentage returns error when set - Added validation for discount value field in Advanced Pricing section of product. --- .../Ui/DataProvider/Product/Form/Modifier/TierPrice.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php index 0eddca3322205..5f8d7fcf9049a 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php @@ -45,7 +45,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * @since 101.1.0 */ public function modifyData(array $data) @@ -54,8 +54,11 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * Add tier price info to meta array. {@inheritdoc} + * * @since 101.1.0 + * @param array $meta + * @return array */ public function modifyMeta(array $meta) { @@ -150,7 +153,9 @@ private function getUpdatedTierPriceStructure(array $priceMeta) 'dataType' => Price::NAME, 'addbefore' => '%', 'validation' => [ + 'required-entry' => true, 'validate-number' => true, + 'validate-greater-than-zero' => true, 'less-than-equals-to' => 100 ], 'visible' => $firstOption From f017676c873418b4e87b306e8666f9db39e82b99 Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Wed, 19 Sep 2018 15:45:48 +0400 Subject: [PATCH 069/812] MAGETWO-91617: Ordered Products Report Error for restricted scope admin - Add fixed code --- .../ActionGroup/AdminOrderActionGroup.xml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml index ffa6a2a5f2d99..aa6c10400d48b 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml @@ -259,16 +259,6 @@ <see selector="{{AdminOrderItemsOrderedSection.productSkuColumn}}" userInput="{{product.sku}}" stepKey="seeSkuInItemsOrdered"/> </actionGroup> - <!--Cancel order that is in pending status--> - <actionGroup name="cancelPendingOrder"> - <click selector="{{AdminOrderDetailsMainActionsSection.cancel}}" stepKey="clickCancelOrder"/> - <waitForElement selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForCancelConfirmation"/> - <see selector="{{AdminConfirmationModalSection.message}}" userInput="Are you sure you want to cancel this order?" stepKey="seeConfirmationMessage"/> - <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmOrderCancel"/> - <see selector="{{AdminMessagesSection.success}}" userInput="You canceled the order." stepKey="seeCancelSuccessMessage"/> - <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Canceled" stepKey="seeOrderStatusCanceled"/> - </actionGroup> - <actionGroup name="CreateOrderInStoreActionGroup"> <arguments> <argument name="product"/> @@ -292,4 +282,14 @@ <click selector="{{OrdersGridSection.submitOrder}}" stepKey="submitOrder"/> <see stepKey="seeSuccessMessageForOrder" userInput="You created the order."/> </actionGroup> + + <!--Cancel order that is in pending status--> + <actionGroup name="cancelPendingOrder"> + <click selector="{{AdminOrderDetailsMainActionsSection.cancel}}" stepKey="clickCancelOrder"/> + <waitForElement selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForCancelConfirmation"/> + <see selector="{{AdminConfirmationModalSection.message}}" userInput="Are you sure you want to cancel this order?" stepKey="seeConfirmationMessage"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmOrderCancel"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You canceled the order." stepKey="seeCancelSuccessMessage"/> + <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Canceled" stepKey="seeOrderStatusCanceled"/> + </actionGroup> </actionGroups> From 5333ca582fcc97c6926df798c96eba3378b7c3e2 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 19 Sep 2018 15:13:26 +0300 Subject: [PATCH 070/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fixed statics. --- .../Test/Unit/Block/Product/ProductList/ToolbarTest.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php index 8282ffa409f9c..884f4c543c8b8 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/ToolbarTest.php @@ -67,13 +67,16 @@ protected function setUp() 'getLimit', 'getCurrentPage' ]); - $this->memorizer = $this->createPartialMock(\Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer::class, [ + $this->memorizer = $this->createPartialMock( + \Magento\Catalog\Model\Product\ProductList\ToolbarMemorizer::class, + [ 'getDirection', 'getOrder', 'getMode', 'getLimit', 'isMemorizingAllowed' - ]); + ] + ); $this->layout = $this->createPartialMock(\Magento\Framework\View\Layout::class, ['getChildName', 'getBlock']); $this->pagerBlock = $this->createPartialMock(\Magento\Theme\Block\Html\Pager::class, [ 'setUseContainer', From 949aa6b9ae92153fa7cd0d0453742259c33ee54c Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 19 Sep 2018 16:17:22 +0300 Subject: [PATCH 071/812] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Fixes according to code review. --- app/code/Magento/GiftMessage/Block/Message/Inline.php | 7 ++----- .../GiftMessage/view/frontend/templates/inline.phtml | 8 +++----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/GiftMessage/Block/Message/Inline.php b/app/code/Magento/GiftMessage/Block/Message/Inline.php index 1a874cb5ea4ae..f44f967cefdc6 100644 --- a/app/code/Magento/GiftMessage/Block/Message/Inline.php +++ b/app/code/Magento/GiftMessage/Block/Message/Inline.php @@ -330,14 +330,11 @@ public function getEscaped($value, $defaultValue = '') * * @return bool */ - public function isOrderLevelAvailable() + public function isMessagesOrderAvailable() { $entity = $this->getEntity(); if (!$entity->hasIsGiftOptionsAvailable()) { $this->_eventManager->dispatch('gift_options_prepare', ['entity' => $entity]); - if (!$entity->getIsGiftOptionsAvailable()) { - $entity->setIsGiftOptionsAvailable($this->isMessagesAvailable()); - } } return $entity->getIsGiftOptionsAvailable(); } @@ -372,7 +369,7 @@ public function isItemMessagesAvailable($item) protected function _toHtml() { // render HTML when messages are allowed for order or for items only - if ($this->isItemsAvailable() || $this->isOrderLevelAvailable()) { + if ($this->isItemsAvailable() || $this->isMessagesAvailable() || $this->isMessagesOrderAvailable()) { return parent::_toHtml(); } return ''; diff --git a/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml b/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml index 8c58959be15b7..640ef1ba16486 100644 --- a/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml +++ b/app/code/Magento/GiftMessage/view/frontend/templates/inline.phtml @@ -18,7 +18,7 @@ </div> <dl class="options-items" id="allow-gift-options-container"> - <?php if ($block->isOrderLevelAvailable()): ?> + <?php if ($block->isMessagesAvailable()): ?> <dt id="add-gift-options-for-order-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" class="order-title"> <div class="field choice"> <input type="checkbox" name="allow_gift_messages_for_order" id="allow_gift_options_for_order" data-mage-init='{"giftOptions":{}}' value="1" data-selector='{"id":"#allow-gift-options-for-order-container"}'<?php if ($block->getEntityHasMessage()): ?> checked="checked"<?php endif; ?> class="checkbox" /> @@ -28,7 +28,6 @@ <dd id="allow-gift-options-for-order-container" class="order-options"> <div class="options-order-container" id="options-order-container-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>"></div> - <?php if ($block->isMessagesAvailable()): ?> <button class="action action-gift" data-mage-init='{"toggleAdvanced": {"selectorsToggleClass":"hidden", "toggleContainers":"#allow-gift-messages-for-order-container"}}'> <span><?= /* @escapeNotVerified */ __('Gift Message') ?></span> @@ -63,9 +62,8 @@ }); </script> </div> - <?php endif; ?> </dd> - <?php endif; ?> + <?php endif ?> <?php if ($block->isItemsAvailable()): ?> <dt id="add-gift-options-for-items-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" class="order-title individual"> <div class="field choice"> @@ -154,7 +152,7 @@ </div> <dl class="options-items" id="allow-gift-options-container-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>"> - <?php if ($block->isOrderLevelAvailable()): ?> + <?php if ($block->isMessagesOrderAvailable() || $block->isMessagesAvailable()): ?> <dt id="add-gift-options-for-order-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" class="order-title"> <div class="field choice"> <input type="checkbox" name="allow_gift_options_for_order_<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" id="allow_gift_options_for_order_<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>" data-mage-init='{"giftOptions":{}}' value="1" data-selector='{"id":"#allow-gift-options-for-order-container-<?= /* @escapeNotVerified */ $block->getEntity()->getId() ?>"}'<?php if ($block->getEntityHasMessage()): ?> checked="checked"<?php endif; ?> class="checkbox" /> From 9302a4f3f22217c6a71002ce009ba3d8ae4897b4 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Wed, 19 Sep 2018 15:45:28 +0200 Subject: [PATCH 072/812] Increased limiter values for passing the tests --- app/code/Magento/GraphQl/etc/di.xml | 4 +- .../Framework/QueryComplexityLimiterTest.php | 133 +++++++++++++++++- .../GraphQl/Query/QueryComplexityLimiter.php | 4 +- 3 files changed, 134 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index b1d24ce6c4a55..622888f697b84 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -99,8 +99,8 @@ </type> <type name="Magento\Framework\GraphQl\Query\QueryComplexityLimiter"> <arguments> - <argument name="queryDepth" xsi:type="number">15</argument> - <argument name="queryComplexity" xsi:type="number">50</argument> + <argument name="queryDepth" xsi:type="number">20</argument> + <argument name="queryComplexity" xsi:type="number">160</argument> </arguments> </type> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php index 4616c450786ed..3304d9e6198f4 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php @@ -90,6 +90,127 @@ public function testQueryComplexityIsLimited() id types } + categories { + id + position + level + url_key + url_path + product_count + breadcrumbs { + category_id + category_name + category_url_key + } + products { + items { + name + special_from_date + special_to_date + new_to_date + new_from_date + tier_price + manufacturer + thumbnail + sku + image + canonical_url + updated_at + created_at + categories { + id + position + level + url_key + url_path + product_count + breadcrumbs { + category_id + category_name + category_url_key + } + products { + items { + name + special_from_date + special_to_date + new_to_date + new_from_date + tier_price + manufacturer + sku + image + canonical_url + updated_at + created_at + categories { + id + position + level + url_key + url_path + product_count + breadcrumbs { + category_id + category_name + category_url_key + } + products { + items { + name + special_from_date + special_to_date + new_to_date + new_from_date + tier_price + manufacturer + sku + image + thumbnail + canonical_url + updated_at + created_at + categories { + id + position + position + position + position + position + position + position + position + position + position + position + position + position + position + position + position + position + position + position + level + url_key + url_path + product_count + default_sort_by + breadcrumbs { + category_id + category_name + category_url_key + } + } + } + } + } + } + } + } + } + } + } } } } @@ -102,7 +223,7 @@ public function testQueryComplexityIsLimited() } QUERY; - self::expectExceptionMessageRegExp('/Max query complexity should be 50 but got 62/'); + self::expectExceptionMessageRegExp('/Max query complexity should be 160 but got 169/'); $this->graphQlQuery($query); } @@ -139,7 +260,13 @@ public function testQueryDepthIsLimited() categories { products { items { - name + categories { + products { + items { + name + } + } + } } } } @@ -163,7 +290,7 @@ public function testQueryDepthIsLimited() } } QUERY; - self::expectExceptionMessageRegExp('/Max query depth should be 15 but got 20/'); + self::expectExceptionMessageRegExp('/Max query depth should be 20 but got 23/'); $this->graphQlQuery($query); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index b302f4272527a..3936da21fc56a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -38,8 +38,8 @@ class QueryComplexityLimiter * @param int $queryComplexity */ public function __construct( - int $queryDepth = 15, - int $queryComplexity = 50 + int $queryDepth = 20, + int $queryComplexity = 160 ) { $this->queryDepth = $queryDepth; $this->queryComplexity = $queryComplexity; From 8024b4c1c2a5c3a28c42805c3d52edea536f7501 Mon Sep 17 00:00:00 2001 From: "Hakobyan, Lusine" <Lusine_Hakobyan@epam.com> Date: Thu, 20 Sep 2018 11:24:47 +0400 Subject: [PATCH 073/812] MAGETWO-91704: Can't cancel/change payment method after chosen Store Credit - Update automated test according to review --- .../Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml index 8aaf626edab33..24ff30071830f 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml @@ -9,7 +9,6 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminOrderFormPaymentSection"> - <element name="useCustomerBalance" type="checkbox" selector="#p_method_use_customerbalance"/> <element name="header" type="text" selector="#order-methods span.title"/> <element name="getShippingMethods" type="text" selector="#order-shipping_method a.action-default" timeout="30"/> <element name="flatRateOption" type="radio" selector="#s_method_flatrate_flatrate" timeout="30"/> From a43f6603f2114ddaaebc5e76616d0c315e86203b Mon Sep 17 00:00:00 2001 From: vprohorov <prohorov.vital@gmail.com> Date: Wed, 19 Sep 2018 02:50:20 +0300 Subject: [PATCH 074/812] MAGETWO-91537: Search synonyms results missing for words including hyphen and numbers - Removing hyphen from SPECIAL_CHARACTERS constant --- .../Search/Adapter/Mysql/Query/Builder/Match.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php index 8e3758817adf0..28e321d4c5d47 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php @@ -15,11 +15,16 @@ use Magento\Framework\Search\Adapter\Preprocessor\PreprocessorInterface; /** + * Class for building select where condition. + * * @api */ class Match implements QueryInterface { - const SPECIAL_CHARACTERS = '-+~/\\<>\'":*$#@()!,.?`=%&^'; + /** + * @var string + */ + const SPECIAL_CHARACTERS = '+~/\\<>\'":*$#@()!,.?`=%&^'; const MINIMAL_CHARACTER_LENGTH = 3; @@ -69,7 +74,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function build( ScoreBuilder $scoreBuilder, @@ -113,6 +118,8 @@ public function build( } /** + * Prepare query value for build function. + * * @param string $queryValue * @param string $conditionType * @return string From 0d191b7ad858f0c4ef0e468b0a288861e5d2d5f2 Mon Sep 17 00:00:00 2001 From: eugene-shab <dev.eugene.shab@gmail.com> Date: Thu, 20 Sep 2018 11:57:51 +0300 Subject: [PATCH 075/812] Add label param to the image. --- .../Model/Resolver/Product/ProductImage.php | 10 ++++++---- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 6 ++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php index 3cf961c0f4225..9dc0dd68ee457 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php @@ -64,15 +64,17 @@ public function resolve( /** @var \Magento\Catalog\Helper\Image $catalogImageHelper */ $catalogImageHelper = $this->catalogImageHelperFactory->create(); - $imageUrl = $catalogImageHelper->init( + /** @var \Magento\Catalog\Helper\Image $image */ + $image = $catalogImageHelper->init( $product, 'product_' . $imageType, ['type' => $imageType] - )->getUrl(); + ); $imageData = [ - 'url' => $imageUrl, - 'path' => $product->getData($imageType) + 'url' => $image->getUrl(), + 'path' => $product->getData($imageType), + 'label' => $image->getLabel() ]; return $imageData; diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 683dfb8de1f26..4a382e16447a4 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -264,9 +264,6 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ new_to_date: String @doc(description: "The end date for new product listings") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\NewFromTo") tier_price: Float @doc(description: "The price when tier pricing is in effect and the items purchased threshold has been reached") options_container: String @doc(description: "If the product has multiple options, determines where they appear on the product page") - image_label: String @doc(description: "The label assigned to a product image") - small_image_label: String @doc(description: "The label assigned to a product's small image") - thumbnail_label: String @doc(description: "The label assigned to a product's thumbnail image") created_at: String @doc(description: "Timestamp indicating when the product was created") updated_at: String @doc(description: "Timestamp indicating when the product was updated") country_of_manufacture: String @doc(description: "The product's country of origin") @@ -352,9 +349,10 @@ type CustomizableFileValue @doc(description: "CustomizableFileValue defines the image_size_y: Int @doc(description: "The maximum height of an image") } -type ProductImage @doc(description: "Product image information. Contains image relative path and URL") { +type ProductImage @doc(description: "Product image information. Contains image relative path, URL and label") { url: String path: String + label: String } interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CustomizableOptionTypeResolver") @doc(description: "The CustomizableOptionInterface contains basic information about a customizable option. It can be implemented by several types of configurable options.") { From d3df40b11e75968eb78acee4cae47d27a3a5716c Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Thu, 20 Sep 2018 12:52:22 +0300 Subject: [PATCH 076/812] MAGETWO-94429: [2.3] Files and folders symlinked in pub/media cannot be deleted from media gallery browser --- .../Framework/Filesystem/Driver/FileTest.php | 75 ++++++++++++++++--- .../Framework/Filesystem/Driver/File.php | 15 +++- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Filesystem/Driver/FileTest.php b/dev/tests/integration/testsuite/Magento/Framework/Filesystem/Driver/FileTest.php index 26401c782efc4..5f53e62165502 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Filesystem/Driver/FileTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Filesystem/Driver/FileTest.php @@ -7,22 +7,27 @@ */ namespace Magento\Framework\Filesystem\Driver; -use Magento\Framework\Filesystem\DriverInterface; +use Magento\Framework\Exception\FileSystemException; class FileTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Framework\Filesystem\Driver\File + * @var File */ - protected $driver; + private $driver; /** - * @var string + * @var String */ - protected $absolutePath; + private $absolutePath; /** - * get relative path for test + * @var String + */ + private $generatedPath; + + /** + * Returns relative path for the test. * * @param $relativePath * @return string @@ -33,16 +38,26 @@ protected function getTestPath($relativePath) } /** - * Set up + * @inheritdoc */ public function setUp() { - $this->driver = new \Magento\Framework\Filesystem\Driver\File(); + $this->driver = new File(); $this->absolutePath = dirname(__DIR__) . '/_files/'; + $this->generatedPath = $this->getTestPath('generated'); + $this->removeGeneratedDirectory(); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->removeGeneratedDirectory(); } /** - * test read recursively read + * Tests directory recursive read. */ public function testReadDirectoryRecursively() { @@ -60,7 +75,7 @@ public function testReadDirectoryRecursively() } /** - * test exception + * Tests directory reading exception. * * @expectedException \Magento\Framework\Exception\FileSystemException */ @@ -69,6 +84,11 @@ public function testReadDirectoryRecursivelyFailure() $this->driver->readDirectoryRecursively($this->getTestPath('not-existing-directory')); } + /** + * Tests of directory creating. + * + * @throws FileSystemException + */ public function testCreateDirectory() { $generatedPath = $this->getTestPath('generated/roo/bar/baz/foo'); @@ -80,4 +100,39 @@ public function testCreateDirectory() $this->assertTrue($this->driver->createDirectory($generatedPath)); $this->assertTrue(is_dir($generatedPath)); } + + /** + * Tests creation and removing of symlinks. + * + * @throws FileSystemException + * @return void + */ + public function testSymlinks(): void + { + $sourceDirectory = $this->generatedPath . '/source'; + $destinationDirectory = $this->generatedPath . '/destination'; + + $this->driver->createDirectory($sourceDirectory); + $this->driver->createDirectory($destinationDirectory); + + $linkName = $destinationDirectory . '/link'; + + self::assertTrue($this->driver->isWritable($destinationDirectory)); + self::assertTrue($this->driver->symlink($sourceDirectory, $linkName)); + self::assertTrue($this->driver->isExists($linkName)); + self::assertTrue($this->driver->deleteDirectory($linkName)); + } + + /** + * Remove generated directories. + * + * @throws FileSystemException + * @return void + */ + private function removeGeneratedDirectory(): void + { + if (is_dir($this->generatedPath)) { + $this->driver->deleteDirectory($this->generatedPath); + } + } } diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/File.php b/lib/internal/Magento/Framework/Filesystem/Driver/File.php index b54b02bd6de98..499d1f5adc9f3 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/File.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/File.php @@ -14,6 +14,7 @@ /** * Class File + * * @package Magento\Framework\Filesystem\Driver * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ @@ -409,7 +410,14 @@ public function deleteDirectory($path) $this->deleteFile($entity->getPathname()); } } - $result = @rmdir($this->getScheme() . $path); + + $fullPath = $this->getScheme() . $path; + if (is_link($fullPath)) { + $result = @unlink($fullPath); + } else { + $result = @rmdir($fullPath); + } + if (!$result) { throw new FileSystemException( new \Magento\Framework\Phrase( @@ -843,6 +851,8 @@ public function fileUnlock($resource) } /** + * Returns an absolute path for the given one. + * * @param string $basePath * @param string $path * @param string|null $scheme @@ -879,7 +889,8 @@ public function getRelativePath($basePath, $path = null) } /** - * Fixes path separator + * Fixes path separator. + * * Utility method. * * @param string $path From 6e20bdd2d7e4bc3b177980620eac2161281f10ae Mon Sep 17 00:00:00 2001 From: Aleksey Tsoy <aleksey_tsoy@epam.com> Date: Thu, 20 Sep 2018 16:55:49 +0600 Subject: [PATCH 077/812] MAGETWO-91658: Wrong Checkout Totals Sort Order in cart - Added automated test --- .../Mftf/ActionGroup/CheckoutActionGroup.xml | 8 ++ .../Test/Mftf/Data/CheckoutConfigData.xml | 25 ++++++ .../Mftf/Metadata/checkout_config-meta.xml | 86 +++++++++++++++++++ .../Section/CheckoutCartSummarySection.xml | 1 + .../CheckoutTotalsSortOrderInCartTest.xml | 53 ++++++++++++ .../Test/Mftf/Data/SalesRuleData.xml | 29 +++++++ 6 files changed, 202 insertions(+) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml create mode 100644 app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index 41be15d0ca410..01a7d8ead9132 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -86,6 +86,14 @@ <see userInput="${{total}}" selector="{{CheckoutPaymentSection.orderSummaryTotal}}" stepKey="assertTotal"/> </actionGroup> + <actionGroup name="CheckTotalsSortOrderInSummarySection"> + <arguments> + <argument name="elementName" type="string"/> + <argument name="positionNumber" type="integer"/> + </arguments> + <see userInput="{{elementName}}" selector="{{CheckoutCartSummarySection.elementPosition(positionNumber)}}" stepKey="assertElementPosition"/> + </actionGroup> + <!-- Check ship to information in checkout --> <actionGroup name="CheckShipToInformationInCheckoutActionGroup"> <arguments> diff --git a/app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml b/app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml new file mode 100644 index 0000000000000..bf2ae28009011 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml @@ -0,0 +1,25 @@ +<?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="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="CheckoutShippingTotalsSortOrder" type="checkout_totals_sort_order"> + <requiredEntity type="shipping">ShippingTotalsSortOrder</requiredEntity> + </entity> + + <entity name="ShippingTotalsSortOrder" type="shipping"> + <data key="value">27</data> + </entity> + + <entity name="DefaultCheckoutTotalsSortOrder" type="default_checkout_totals_sort_order"> + <requiredEntity type="checkoutTotalFlagZero">DefaultTotalFlagZero</requiredEntity> + </entity> + <entity name="DefaultTotalFlagZero" type="checkoutTotalFlagZero"> + <data key="value">0</data> + </entity> +</entities> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml b/app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml new file mode 100644 index 0000000000000..55572ee73ac46 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml @@ -0,0 +1,86 @@ +<?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="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> + <operation name="SetCheckoutTotalsSortOrder" dataType="checkout_totals_sort_order" type="create" auth="adminFormKey" url="/admin/system_config/save/section/sales/" method="POST"> + <object key="groups" dataType="checkout_totals_sort_order"> + <object key="totals_sort" dataType="checkout_totals_sort_order"> + <object key="fields" dataType="checkout_totals_sort_order"> + <object key="subtotal" dataType="subtotal"> + <field key="value">integer</field> + </object> + <object key="discount" dataType="discount"> + <field key="value">integer</field> + </object> + <object key="shipping" dataType="shipping"> + <field key="value">integer</field> + </object> + <object key="tax" dataType="tax"> + <field key="value">integer</field> + </object> + <object key="weee" dataType="weee"> + <field key="value">integer</field> + </object> + <object key="grand_total" dataType="grand_total"> + <field key="value">integer</field> + </object> + <object key="giftcardaccount" dataType="giftcardaccount"> + <field key="value">integer</field> + </object> + <object key="customerbalance" dataType="customerbalance"> + <field key="value">integer</field> + </object> + </object> + </object> + </object> + </operation> + + <operation name="DefaultCheckoutTotalsSortOrder" dataType="default_checkout_totals_sort_order" type="create" auth="adminFormKey" url="/admin/system_config/save/section/sales/" method="POST"> + <object key="groups" dataType="default_checkout_totals_sort_order"> + <object key="totals_sort" dataType="default_checkout_totals_sort_order"> + <object key="fields" dataType="default_checkout_totals_sort_order"> + <object key="subtotal" dataType="default_checkout_totals_sort_order"> + <object key="inherit" dataType="checkoutTotalFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="discount" dataType="default_checkout_totals_sort_order"> + <object key="inherit" dataType="checkoutTotalFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="shipping" dataType="default_checkout_totals_sort_order"> + <object key="inherit" dataType="checkoutTotalFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="tax" dataType="default_checkout_totals_sort_order"> + <object key="inherit" dataType="checkoutTotalFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="weee" dataType="default_checkout_totals_sort_order"> + <object key="inherit" dataType="checkoutTotalFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="grand_total" dataType="default_checkout_totals_sort_order"> + <object key="inherit" dataType="checkoutTotalFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="giftcardaccount" dataType="giftcardaccount"> + <field key="value">integer</field> + </object> + <object key="customerbalance" dataType="customerbalance"> + <field key="value">integer</field> + </object> + </object> + </object> + </object> + </operation> +</operations> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml index a1a8d2ba3eade..b1547f2ef4d92 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml @@ -9,6 +9,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="CheckoutCartSummarySection"> + <element name="elementPosition" type="text" selector=".data.table.totals > tbody tr:nth-of-type({{value}}) > th" parameterized="true"/> <element name="subtotal" type="text" selector="//*[@id='cart-totals']//tr[@class='totals sub']//td//span[@class='price']"/> <element name="shippingMethod" type="text" selector="//*[@id='cart-totals']//tr[@class='totals shipping excl']//th//span[@class='value']"/> <element name="shipping" type="text" selector="//*[@id='cart-totals']//tr[@class='totals shipping excl']//td//span[@class='price']"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml new file mode 100644 index 0000000000000..e1ec9032e072a --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml @@ -0,0 +1,53 @@ +<?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="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="CheckoutTotalsSortOrderInCartTest"> + <annotations> + <title value="Checkout Totals Sort Order configuration and displaying in cart"/> + <stories value="MAGETWO-91658: Wrong Checkout Totals Sort Order in cart"/> + <description value="Checkout Totals Sort Order configuration and displaying in cart"/> + <features value="Checkout"/> + <severity value="AVERAGE"/> + <testCaseId value="MAGETWO-94944"/> + <group value="Checkout"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="defaultCategory"/> + <createData entity="SimpleProduct" stepKey="simpleProduct"> + <requiredEntity createDataKey="defaultCategory"/> + </createData> + + <createData entity="ApiCartRule" stepKey="cartRule"/> + + <createData entity="CheckoutShippingTotalsSortOrder" stepKey="setConfigShippingTotalsSortOrder"/> + </before> + + <actionGroup ref="VerifyDiscountAmount" stepKey="verifyStorefront"> + <argument name="productUrl" value="$$simpleProduct.sku$$.html"/> + <argument name="quantity" value="1"/> + <argument name="expectedDiscount" value="-$61.50"/> + </actionGroup> + + <actionGroup ref="CheckTotalsSortOrderInSummarySection" stepKey="checkTotalsSortOrderInSummarySection"> + <argument name="elementName" value="Shipping (Flat Rate - Fixed)"/> + <argument name="positionNumber" value="3"/> + </actionGroup> + + <after> + <createData entity="DefaultCheckoutTotalsSortOrder" stepKey="setDefaultTotalsSortOrder"/> + + <deleteData createDataKey="cartRule" stepKey="deleteCartRule"/> + <deleteData createDataKey="simpleProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="defaultCategory" stepKey="deleteCategory"/> + + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </after> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml b/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml index 5b7585b8b2a3f..2ac4917683450 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml @@ -39,6 +39,35 @@ <requiredEntity type="SalesRuleLabel">SalesRuleLabelStore1</requiredEntity> </entity> + <entity name="ApiCartRule" type="SalesRule"> + <data key="name" unique="suffix">salesRule</data> + <data key="description">Sales Rule Descritpion</data> + <array key="website_ids"> + <item>1</item> + </array> + <array key="customer_group_ids"> + <item>0</item> + <item>1</item> + <item>3</item> + </array> + <data key="uses_per_customer">0</data> + <data key="is_active">true</data> + <data key="stop_rules_processing">true</data> + <data key="is_advanced">true</data> + <data key="sort_order">0</data> + <data key="simple_action">by_percent</data> + <data key="discount_amount">50</data> + <data key="discount_qty">0</data> + <data key="discount_step">0</data> + <data key="apply_to_shipping">false</data> + <data key="times_used">0</data> + <data key="is_rss">true</data> + <data key="coupon_type">NO_COUPON</data> + <data key="use_auto_generation">false</data> + <data key="uses_per_coupon">0</data> + <data key="simple_free_shipping">0</data> + </entity> + <entity name="SimpleSalesRule" type="SalesRule"> <data key="name" unique="suffix">SimpleSalesRule</data> <data key="is_active">true</data> From 10c08ae5c26307668964bf03ad7ef124ffddde5a Mon Sep 17 00:00:00 2001 From: Oksana_Kremen <Oksana_Kremen@epam.com> Date: Thu, 20 Sep 2018 19:36:02 +0300 Subject: [PATCH 078/812] MAGETWO-91733: Unusual behavior with the persistent shopping cart after the session is expired - Added observer to pass customer data from persistent session to checkout session --- ...tCheckoutSessionPersistentDataObserver.php | 90 +++++++++++ .../SetLoadPersistentQuoteObserver.php | 78 --------- ...ckoutSessionPersistentDataObserverTest.php | 149 ++++++++++++++++++ .../SetLoadPersistentQuoteObserverTest.php | 73 --------- .../Persistent/etc/frontend/events.xml | 2 +- .../Persistent/etc/webapi_rest/events.xml | 2 +- .../Persistent/etc/webapi_soap/events.xml | 2 +- 7 files changed, 242 insertions(+), 154 deletions(-) create mode 100644 app/code/Magento/Persistent/Observer/SetCheckoutSessionPersistentDataObserver.php delete mode 100644 app/code/Magento/Persistent/Observer/SetLoadPersistentQuoteObserver.php create mode 100644 app/code/Magento/Persistent/Test/Unit/Observer/SetCheckoutSessionPersistentDataObserverTest.php delete mode 100644 app/code/Magento/Persistent/Test/Unit/Observer/SetLoadPersistentQuoteObserverTest.php diff --git a/app/code/Magento/Persistent/Observer/SetCheckoutSessionPersistentDataObserver.php b/app/code/Magento/Persistent/Observer/SetCheckoutSessionPersistentDataObserver.php new file mode 100644 index 0000000000000..e89a09c0d2a9c --- /dev/null +++ b/app/code/Magento/Persistent/Observer/SetCheckoutSessionPersistentDataObserver.php @@ -0,0 +1,90 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Persistent\Observer; + +use Magento\Framework\Event\ObserverInterface; + +/** + * Class SetCheckoutSessionPersistentDataObserver + */ +class SetCheckoutSessionPersistentDataObserver implements ObserverInterface +{ + /** + * Persistent session + * + * @var \Magento\Persistent\Helper\Session + */ + private $persistentSession = null; + + /** + * Customer session + * + * @var \Magento\Customer\Model\Session + */ + private $customerSession; + + /** + * Persistent data + * + * @var \Magento\Persistent\Helper\Data + */ + private $persistentData = null; + + /** + * Customer Repository + * + * @var \Magento\Customer\Api\CustomerRepositoryInterface + */ + private $customerRepository = null; + + /** + * @param \Magento\Persistent\Helper\Session $persistentSession + * @param \Magento\Customer\Model\Session $customerSession + * @param \Magento\Persistent\Helper\Data $persistentData + * @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository + */ + public function __construct( + \Magento\Persistent\Helper\Session $persistentSession, + \Magento\Customer\Model\Session $customerSession, + \Magento\Persistent\Helper\Data $persistentData, + \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository + ) { + $this->persistentSession = $persistentSession; + $this->customerSession = $customerSession; + $this->persistentData = $persistentData; + $this->customerRepository = $customerRepository; + } + + /** + * Pass customer data from persistent session to checkout session and set quote to be loaded even if not active + * + * @param \Magento\Framework\Event\Observer $observer + * @return void + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function execute(\Magento\Framework\Event\Observer $observer) + { + /** @var $checkoutSession \Magento\Checkout\Model\Session */ + $checkoutSession = $observer->getEvent()->getData('checkout_session'); + if ($this->persistentData->isShoppingCartPersist() && $this->persistentSession->isPersistent()) { + $checkoutSession->setCustomerData( + $this->customerRepository->getById($this->persistentSession->getSession()->getCustomerId()) + ); + } + if (!(($this->persistentSession->isPersistent() && !$this->customerSession->isLoggedIn()) + && !$this->persistentData->isShoppingCartPersist() + )) { + return; + } + if ($checkoutSession) { + $checkoutSession->setLoadInactive(); + } + } +} diff --git a/app/code/Magento/Persistent/Observer/SetLoadPersistentQuoteObserver.php b/app/code/Magento/Persistent/Observer/SetLoadPersistentQuoteObserver.php deleted file mode 100644 index 6eeab94a91cca..0000000000000 --- a/app/code/Magento/Persistent/Observer/SetLoadPersistentQuoteObserver.php +++ /dev/null @@ -1,78 +0,0 @@ -<?php -/** - * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Persistent\Observer; - -use Magento\Framework\Event\ObserverInterface; - -class SetLoadPersistentQuoteObserver implements ObserverInterface -{ - /** - * Customer session - * - * @var \Magento\Customer\Model\Session - */ - protected $_customerSession; - - /** - * Checkout session - * - * @var \Magento\Checkout\Model\Session - */ - protected $_checkoutSession; - - /** - * Persistent session - * - * @var \Magento\Persistent\Helper\Session - */ - protected $_persistentSession = null; - - /** - * Persistent data - * - * @var \Magento\Persistent\Helper\Data - */ - protected $_persistentData = null; - - /** - * @param \Magento\Persistent\Helper\Session $persistentSession - * @param \Magento\Persistent\Helper\Data $persistentData - * @param \Magento\Customer\Model\Session $customerSession - * @param \Magento\Checkout\Model\Session $checkoutSession - */ - public function __construct( - \Magento\Persistent\Helper\Session $persistentSession, - \Magento\Persistent\Helper\Data $persistentData, - \Magento\Customer\Model\Session $customerSession, - \Magento\Checkout\Model\Session $checkoutSession - ) { - $this->_persistentSession = $persistentSession; - $this->_customerSession = $customerSession; - $this->_checkoutSession = $checkoutSession; - $this->_persistentData = $persistentData; - } - - /** - * Set quote to be loaded even if not active - * - * @param \Magento\Framework\Event\Observer $observer - * @return void - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function execute(\Magento\Framework\Event\Observer $observer) - { - if (!(($this->_persistentSession->isPersistent() && !$this->_customerSession->isLoggedIn()) - && !$this->_persistentData->isShoppingCartPersist() - )) { - return; - } - - if ($this->_checkoutSession) { - $this->_checkoutSession->setLoadInactive(); - } - } -} diff --git a/app/code/Magento/Persistent/Test/Unit/Observer/SetCheckoutSessionPersistentDataObserverTest.php b/app/code/Magento/Persistent/Test/Unit/Observer/SetCheckoutSessionPersistentDataObserverTest.php new file mode 100644 index 0000000000000..01c217c1c5cd4 --- /dev/null +++ b/app/code/Magento/Persistent/Test/Unit/Observer/SetCheckoutSessionPersistentDataObserverTest.php @@ -0,0 +1,149 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Persistent\Test\Unit\Observer; + +/** + * Class SetCheckoutSessionPersistentDataObserverTest + */ +class SetCheckoutSessionPersistentDataObserverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Persistent\Observer\SetCheckoutSessionPersistentDataObserver + */ + private $model; + + /** + * @var \Magento\Persistent\Helper\Data| \PHPUnit_Framework_MockObject_MockObject + */ + private $helperMock; + + /** + * @var \Magento\Persistent\Helper\Session| \PHPUnit_Framework_MockObject_MockObject + */ + private $sessionHelperMock; + + /** + * @var \Magento\Checkout\Model\Session| \PHPUnit_Framework_MockObject_MockObject + */ + private $checkoutSessionMock; + + /** + * @var \Magento\Customer\Model\Session| \PHPUnit_Framework_MockObject_MockObject + */ + private $customerSessionMock; + + /** + * @var \Magento\Persistent\Model\Session| \PHPUnit_Framework_MockObject_MockObject + */ + private $persistentSessionMock; + + /** + * @var \Magento\Customer\Api\CustomerRepositoryInterface| \PHPUnit_Framework_MockObject_MockObject + */ + private $customerRepositoryMock; + + /** + * @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject + */ + private $observerMock; + + /** + * @var \Magento\Framework\Event|\PHPUnit_Framework_MockObject_MockObject + */ + private $eventMock; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->helperMock = $this->createMock(\Magento\Persistent\Helper\Data::class); + $this->sessionHelperMock = $this->createMock(\Magento\Persistent\Helper\Session::class); + $this->checkoutSessionMock = $this->createMock(\Magento\Checkout\Model\Session::class); + $this->customerSessionMock = $this->createMock(\Magento\Customer\Model\Session::class); + $this->observerMock = $this->createMock(\Magento\Framework\Event\Observer::class); + $this->eventMock = $this->createPartialMock(\Magento\Framework\Event::class, ['getData']); + $this->persistentSessionMock = $this->createPartialMock( + \Magento\Persistent\Model\Session::class, + ['getCustomerId'] + ); + $this->customerRepositoryMock = $this->createMock( + \Magento\Customer\Api\CustomerRepositoryInterface::class + ); + $this->model = new \Magento\Persistent\Observer\SetCheckoutSessionPersistentDataObserver( + $this->sessionHelperMock, + $this->customerSessionMock, + $this->helperMock, + $this->customerRepositoryMock + ); + } + + /** + * Test execute method when session is not persistent + * + * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function testExecuteWhenSessionIsNotPersistent() + { + $this->observerMock->expects($this->once()) + ->method('getEvent') + ->will($this->returnValue($this->eventMock)); + $this->eventMock->expects($this->once()) + ->method('getData') + ->will($this->returnValue($this->checkoutSessionMock)); + $this->sessionHelperMock->expects($this->once()) + ->method('isPersistent') + ->will($this->returnValue(false)); + $this->checkoutSessionMock->expects($this->never()) + ->method('setLoadInactive'); + $this->checkoutSessionMock->expects($this->never()) + ->method('setCustomerData'); + $this->model->execute($this->observerMock); + } + + /** + * Test execute method when session is persistent + * + * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function testExecute() + { + $this->observerMock->expects($this->once()) + ->method('getEvent') + ->will($this->returnValue($this->eventMock)); + $this->eventMock->expects($this->once()) + ->method('getData') + ->will($this->returnValue($this->checkoutSessionMock)); + $this->sessionHelperMock->expects($this->exactly(2)) + ->method('isPersistent') + ->will($this->returnValue(true)); + $this->customerSessionMock->expects($this->once()) + ->method('isLoggedIn') + ->will($this->returnValue(false)); + $this->helperMock->expects($this->exactly(2)) + ->method('isShoppingCartPersist') + ->will($this->returnValue(true)); + $this->persistentSessionMock->expects($this->once()) + ->method('getCustomerId') + ->will($this->returnValue(123)); + $this->sessionHelperMock->expects($this->once()) + ->method('getSession') + ->will($this->returnValue($this->persistentSessionMock)); + $this->customerRepositoryMock->expects($this->once()) + ->method('getById') + ->will($this->returnValue(true)); //? + $this->checkoutSessionMock->expects($this->never()) + ->method('setLoadInactive'); + $this->checkoutSessionMock->expects($this->once()) + ->method('setCustomerData'); + $this->model->execute($this->observerMock); + } +} diff --git a/app/code/Magento/Persistent/Test/Unit/Observer/SetLoadPersistentQuoteObserverTest.php b/app/code/Magento/Persistent/Test/Unit/Observer/SetLoadPersistentQuoteObserverTest.php deleted file mode 100644 index fd78a6852ea59..0000000000000 --- a/app/code/Magento/Persistent/Test/Unit/Observer/SetLoadPersistentQuoteObserverTest.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Persistent\Test\Unit\Observer; - -class SetLoadPersistentQuoteObserverTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Persistent\Observer\SetLoadPersistentQuoteObserver - */ - protected $model; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $helperMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $sessionHelperMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $checkoutSessionMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $customerSessionMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $observerMock; - - protected function setUp() - { - $this->helperMock = $this->createMock(\Magento\Persistent\Helper\Data::class); - $this->sessionHelperMock = $this->createMock(\Magento\Persistent\Helper\Session::class); - $this->checkoutSessionMock = $this->createMock(\Magento\Checkout\Model\Session::class); - $this->customerSessionMock = $this->createMock(\Magento\Customer\Model\Session::class); - $this->observerMock = $this->createMock(\Magento\Framework\Event\Observer::class); - - $this->model = new \Magento\Persistent\Observer\SetLoadPersistentQuoteObserver( - $this->sessionHelperMock, - $this->helperMock, - $this->customerSessionMock, - $this->checkoutSessionMock - ); - } - - public function testExecuteWhenSessionIsNotPersistent() - { - $this->sessionHelperMock->expects($this->once())->method('isPersistent')->will($this->returnValue(false)); - $this->checkoutSessionMock->expects($this->never())->method('setLoadInactive'); - $this->model->execute($this->observerMock); - } - - public function testExecute() - { - $this->sessionHelperMock->expects($this->once())->method('isPersistent')->will($this->returnValue(true)); - $this->customerSessionMock->expects($this->once())->method('isLoggedIn')->will($this->returnValue(false)); - $this->helperMock->expects($this->once())->method('isShoppingCartPersist')->will($this->returnValue(true)); - $this->checkoutSessionMock->expects($this->never())->method('setLoadInactive'); - $this->model->execute($this->observerMock); - } -} diff --git a/app/code/Magento/Persistent/etc/frontend/events.xml b/app/code/Magento/Persistent/etc/frontend/events.xml index 193b9a10818e4..79720695ea6f6 100644 --- a/app/code/Magento/Persistent/etc/frontend/events.xml +++ b/app/code/Magento/Persistent/etc/frontend/events.xml @@ -49,7 +49,7 @@ <observer name="persistent" instance="Magento\Persistent\Observer\SetQuotePersistentDataObserver" /> </event> <event name="custom_quote_process"> - <observer name="persistent" instance="Magento\Persistent\Observer\SetLoadPersistentQuoteObserver" /> + <observer name="persistent" instance="Magento\Persistent\Observer\SetCheckoutSessionPersistentDataObserver" /> </event> <event name="customer_register_success"> <observer name="persistent" instance="Magento\Persistent\Observer\RemovePersistentCookieOnRegisterObserver" /> diff --git a/app/code/Magento/Persistent/etc/webapi_rest/events.xml b/app/code/Magento/Persistent/etc/webapi_rest/events.xml index 1eff845386bf4..79dffa1834563 100644 --- a/app/code/Magento/Persistent/etc/webapi_rest/events.xml +++ b/app/code/Magento/Persistent/etc/webapi_rest/events.xml @@ -22,7 +22,7 @@ <observer name="persistent" instance="Magento\Persistent\Observer\SetQuotePersistentDataObserver" /> </event> <event name="custom_quote_process"> - <observer name="persistent" instance="Magento\Persistent\Observer\SetLoadPersistentQuoteObserver" /> + <observer name="persistent" instance="Magento\Persistent\Observer\SetCheckoutSessionPersistentDataObserver" /> </event> <event name="customer_register_success"> <observer name="persistent" instance="Magento\Persistent\Observer\RemovePersistentCookieOnRegisterObserver" /> diff --git a/app/code/Magento/Persistent/etc/webapi_soap/events.xml b/app/code/Magento/Persistent/etc/webapi_soap/events.xml index 1eff845386bf4..79dffa1834563 100644 --- a/app/code/Magento/Persistent/etc/webapi_soap/events.xml +++ b/app/code/Magento/Persistent/etc/webapi_soap/events.xml @@ -22,7 +22,7 @@ <observer name="persistent" instance="Magento\Persistent\Observer\SetQuotePersistentDataObserver" /> </event> <event name="custom_quote_process"> - <observer name="persistent" instance="Magento\Persistent\Observer\SetLoadPersistentQuoteObserver" /> + <observer name="persistent" instance="Magento\Persistent\Observer\SetCheckoutSessionPersistentDataObserver" /> </event> <event name="customer_register_success"> <observer name="persistent" instance="Magento\Persistent\Observer\RemovePersistentCookieOnRegisterObserver" /> From 441a98190a29baa239b419fdb2f492ef3a82431d Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 21 Sep 2018 09:08:55 +0200 Subject: [PATCH 079/812] Added correct path to the phpunit file --- .travis.yml | 3 ++- dev/tests/api-functional/phpunit_graphql.xml.dist | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e909bb1980752..a80460095ce01 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,5 +62,6 @@ script: # The scripts for grunt/phpunit type tests - if [ $TEST_SUITE == "functional" ]; then dev/tests/functional/vendor/phpunit/phpunit/phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi + - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js" ] && [ $TEST_SUITE != "api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi + - if [ $TEST_SUITE == "api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE/phpunit_graphql.xml.dist; fi - if [ $TEST_SUITE == "js" ]; then grunt $GRUNT_COMMAND; fi diff --git a/dev/tests/api-functional/phpunit_graphql.xml.dist b/dev/tests/api-functional/phpunit_graphql.xml.dist index 4a57c338ca3a2..955a3a8953fa8 100644 --- a/dev/tests/api-functional/phpunit_graphql.xml.dist +++ b/dev/tests/api-functional/phpunit_graphql.xml.dist @@ -27,7 +27,7 @@ <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/> <const name="TESTS_GLOBAL_CONFIG_FILE" value="config/config-global.php"/> <!-- Webserver URL --> - <const name="TESTS_BASE_URL" value="http://magento.url"/> + <const name="TESTS_BASE_URL" value="http://magento2.travis"/> <!-- Webserver API user --> <const name="TESTS_WEBSERVICE_USER" value="admin"/> <!-- Webserver API key --> From df755861a85c2087ba71e7adfa0884fdf46c2544 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 21 Sep 2018 10:55:42 +0200 Subject: [PATCH 080/812] Test api-functional execution with phpunit.xml.dist --- .travis.yml | 4 +- dev/tests/api-functional/phpunit.xml.dist | 56 +++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 dev/tests/api-functional/phpunit.xml.dist diff --git a/.travis.yml b/.travis.yml index a80460095ce01..c6077564b923d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,6 +62,6 @@ script: # The scripts for grunt/phpunit type tests - if [ $TEST_SUITE == "functional" ]; then dev/tests/functional/vendor/phpunit/phpunit/phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js" ] && [ $TEST_SUITE != "api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - - if [ $TEST_SUITE == "api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE/phpunit_graphql.xml.dist; fi + - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi + #- if [ $TEST_SUITE == "api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE/phpunit_graphql.xml.dist; fi - if [ $TEST_SUITE == "js" ]; then grunt $GRUNT_COMMAND; fi diff --git a/dev/tests/api-functional/phpunit.xml.dist b/dev/tests/api-functional/phpunit.xml.dist new file mode 100644 index 0000000000000..955a3a8953fa8 --- /dev/null +++ b/dev/tests/api-functional/phpunit.xml.dist @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * PHPUnit configuration for GraphQL web API functional tests. + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.2/phpunit.xsd" + colors="true" + columns="max" + beStrictAboutTestsThatDoNotTestAnything="false" + bootstrap="./framework/bootstrap.php" +> + <!-- Test suites definition --> + <testsuites> + <testsuite name="Magento GraphQL web API functional tests"> + <directory suffix="Test.php">testsuite/Magento/GraphQl</directory> + </testsuite> + </testsuites> + + <!-- PHP INI settings and constants definition --> + <php> + <includePath>./testsuite</includePath> + <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/> + <const name="TESTS_GLOBAL_CONFIG_FILE" value="config/config-global.php"/> + <!-- Webserver URL --> + <const name="TESTS_BASE_URL" value="http://magento2.travis"/> + <!-- Webserver API user --> + <const name="TESTS_WEBSERVICE_USER" value="admin"/> + <!-- Webserver API key --> + <const name="TESTS_WEBSERVICE_APIKEY" value="123123q"/> + <!-- Define if debugger should be started using XDEBUG_SESSION cookie --> + <const name="TESTS_XDEBUG_ENABLED" value="false"/> + <!-- Define XDEBUG_SESSION cookie value--> + <const name="TESTS_XDEBUG_SESSION" value="phpstorm" /> + + <ini name="date.timezone" value="America/Los_Angeles"/> + + <!-- Semicolon-separated 'glob' patterns, that match global XML configuration files --> + <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> + <!-- Whether to cleanup the application before running tests or not --> + <const name="TESTS_CLEANUP" value="enabled"/> + <!--Defines if Magento should be installed before tests execution--> + <const name="TESTS_MAGENTO_INSTALLATION" value="disabled"/> + <!-- Magento mode for tests execution. Possible values are "default", "developer" and "production". --> + <const name="TESTS_MAGENTO_MODE" value="default"/> + </php> + + <!-- Test listeners --> + <listeners> + <listener class="Magento\TestFramework\Event\PhpUnit"/> + </listeners> +</phpunit> From 636142edf17227f7d72ccf0d13555971276aa6f7 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 21 Sep 2018 11:16:01 +0200 Subject: [PATCH 081/812] Test api-functional execution with production mode enabled --- dev/tests/api-functional/phpunit.xml.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/api-functional/phpunit.xml.dist b/dev/tests/api-functional/phpunit.xml.dist index 955a3a8953fa8..a55531aba87e2 100644 --- a/dev/tests/api-functional/phpunit.xml.dist +++ b/dev/tests/api-functional/phpunit.xml.dist @@ -46,7 +46,7 @@ <!--Defines if Magento should be installed before tests execution--> <const name="TESTS_MAGENTO_INSTALLATION" value="disabled"/> <!-- Magento mode for tests execution. Possible values are "default", "developer" and "production". --> - <const name="TESTS_MAGENTO_MODE" value="default"/> + <const name="TESTS_MAGENTO_MODE" value="production"/> </php> <!-- Test listeners --> From 1148f85e42022e77817e33a901bef5153a7cf108 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Fri, 21 Sep 2018 15:11:30 +0300 Subject: [PATCH 082/812] MAGETWO-59265: Import doesn't allow to set default value per store view (dropdown fields) - Changed logic of setting default value of attributes by store view during import --- .../Model/Import/Product/Type/AbstractType.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php index 8b04b7ec3532f..3b6caef66ce6c 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php @@ -543,10 +543,9 @@ public function prepareAttributesWithDefaultValueForSave(array $rowData, $withDe } else { $resultAttrs[$attrCode] = $rowData[$attrCode]; } - } elseif (array_key_exists($attrCode, $rowData)) { + } elseif (array_key_exists($attrCode, $rowData) && empty($rowData['_store'])) { $resultAttrs[$attrCode] = $rowData[$attrCode]; - } elseif ($withDefaultValue && null !== $attrParams['default_value'] - && 'select' == $attrParams['type'] && null === $rowData['_store']) { + } elseif ($withDefaultValue && null !== $attrParams['default_value'] && empty($rowData['_store'])) { $resultAttrs[$attrCode] = $attrParams['default_value']; } } From bb949b4f3a0322f1ab73b19c2680d12859294038 Mon Sep 17 00:00:00 2001 From: Aleksey Tsoy <aleksey_tsoy@epam.com> Date: Fri, 21 Sep 2018 20:50:29 +0600 Subject: [PATCH 083/812] MAGETWO-91745: Product pages load blank page - Added automated test --- .../Mftf/Data/CatalogAttributeSetData.xml | 16 ++++++++++++ .../Catalog/Test/Mftf/Data/ProductData.xml | 14 +++++++++++ .../Metadata/catalog_attribute_set-meta.xml | 25 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/CatalogAttributeSetData.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_attribute_set-meta.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogAttributeSetData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogAttributeSetData.xml new file mode 100644 index 0000000000000..d78c03a51dd75 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogAttributeSetData.xml @@ -0,0 +1,16 @@ +<?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="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="CatalogAttributeSet" type="CatalogAttributeSet"> + <data key="attribute_set_name" unique="suffix">test_set_</data> + <data key="attributeGroupId">7</data> + <data key="skeletonId">4</data> + </entity> +</entities> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index 9ae551b69d388..3da3272567c9d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -301,6 +301,20 @@ <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> <requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity> </entity> + <entity name="SimpleProductWithCustomAttributeSet" type="product"> + <data key="sku" unique="suffix">testSku</data> + <data key="type_id">simple</data> + <var key="attribute_set_id" entityKey="attribute_set_id" entityType="CatalogAttributeSet"/> + <data key="visibility">4</data> + <data key="name" unique="suffix">testProductName</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">testurlkey</data> + <data key="status">1</data> + <data key="weight">1</data> + <data key="quantity">100</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity> + </entity> <entity name="productWithOptions" type="product"> <var key="sku" entityType="product" entityKey="sku" /> <data key="file">magento.jpg</data> diff --git a/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_attribute_set-meta.xml b/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_attribute_set-meta.xml new file mode 100644 index 0000000000000..9ef7b507812a0 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_attribute_set-meta.xml @@ -0,0 +1,25 @@ +<?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="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> + <operation name="AddCatalogAttributeToAttributeSet" dataType="CatalogAttributeSet" type="create" auth="adminOauth" url="/V1/products/attribute-sets" method="POST"> + <contentType>application/json</contentType> + <object key="attributeSet" dataType="CatalogAttributeSet"> + <field key="attribute_set_name">string</field> + <field key="sort_order">integer</field> + </object> + <field key="skeletonId">integer</field> + </operation> + <operation name="DeleteCatalogAttributeFromAttributeSet" dataType="CatalogAttributeSet" type="delete" auth="adminOauth" url="/V1/products/attribute-sets/{attribute_set_id}" method="DELETE"> + <contentType>application/json</contentType> + </operation> + <operation name="GetCatalogAttributesFromDefaultSet" dataType="CatalogAttributeSet" type="get" auth="adminOauth" url="/V1/products/attribute-sets/{attribute_set_id}" method="GET"> + <contentType>application/json</contentType> + </operation> +</operations> \ No newline at end of file From b35b68130265163f2ed151ff94e0d9f7fc63d44c Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Fri, 21 Sep 2018 18:57:25 +0300 Subject: [PATCH 084/812] MAGETWO-91702: Shipping method Table Rates settings gets from wrong store - Get store id from quote for shipping rates --- .../Magento/Quote/Model/Quote/Address.php | 90 +++++++++---------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/app/code/Magento/Quote/Model/Quote/Address.php b/app/code/Magento/Quote/Model/Quote/Address.php index 3eb5d68885035..11beffe5711b9 100644 --- a/app/code/Magento/Quote/Model/Quote/Address.php +++ b/app/code/Magento/Quote/Model/Quote/Address.php @@ -965,6 +965,7 @@ public function collectShippingRates() /** * Request shipping rates for entire address or specified address item + * * Returns true if current selected shipping method code corresponds to one of the found rates * * @param \Magento\Quote\Model\Quote\Item\AbstractItem $item @@ -1002,7 +1003,7 @@ public function requestShippingRates(\Magento\Quote\Model\Quote\Item\AbstractIte /** * Store and website identifiers specified from StoreManager */ - $request->setStoreId($this->storeManager->getStore()->getId()); + $request->setStoreId($this->getQuote()->getStoreId() ?? $this->storeManager->getStore()->getId()); $request->setWebsiteId($this->storeManager->getWebsite()->getId()); $request->setFreeShipping($this->getFreeShipping()); /** @@ -1348,7 +1349,7 @@ public function getAllBaseTotalAmounts() /******************************* End Total Collector Interface *******************************************/ /** - * {@inheritdoc} + * @inheritdoc */ protected function _getValidationRulesBeforeSave() { @@ -1356,7 +1357,7 @@ protected function _getValidationRulesBeforeSave() } /** - * {@inheritdoc} + * @inheritdoc */ public function getCountryId() { @@ -1364,7 +1365,7 @@ public function getCountryId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCountryId($countryId) { @@ -1372,7 +1373,7 @@ public function setCountryId($countryId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getStreet() { @@ -1381,7 +1382,7 @@ public function getStreet() } /** - * {@inheritdoc} + * @inheritdoc */ public function setStreet($street) { @@ -1389,7 +1390,7 @@ public function setStreet($street) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCompany() { @@ -1397,7 +1398,7 @@ public function getCompany() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCompany($company) { @@ -1405,7 +1406,7 @@ public function setCompany($company) } /** - * {@inheritdoc} + * @inheritdoc */ public function getTelephone() { @@ -1413,7 +1414,7 @@ public function getTelephone() } /** - * {@inheritdoc} + * @inheritdoc */ public function setTelephone($telephone) { @@ -1421,7 +1422,7 @@ public function setTelephone($telephone) } /** - * {@inheritdoc} + * @inheritdoc */ public function getFax() { @@ -1429,7 +1430,7 @@ public function getFax() } /** - * {@inheritdoc} + * @inheritdoc */ public function setFax($fax) { @@ -1437,7 +1438,7 @@ public function setFax($fax) } /** - * {@inheritdoc} + * @inheritdoc */ public function getPostcode() { @@ -1445,7 +1446,7 @@ public function getPostcode() } /** - * {@inheritdoc} + * @inheritdoc */ public function setPostcode($postcode) { @@ -1453,7 +1454,7 @@ public function setPostcode($postcode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCity() { @@ -1461,7 +1462,7 @@ public function getCity() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCity($city) { @@ -1469,7 +1470,7 @@ public function setCity($city) } /** - * {@inheritdoc} + * @inheritdoc */ public function getFirstname() { @@ -1477,7 +1478,7 @@ public function getFirstname() } /** - * {@inheritdoc} + * @inheritdoc */ public function setFirstname($firstname) { @@ -1485,7 +1486,7 @@ public function setFirstname($firstname) } /** - * {@inheritdoc} + * @inheritdoc */ public function getLastname() { @@ -1493,7 +1494,7 @@ public function getLastname() } /** - * {@inheritdoc} + * @inheritdoc */ public function setLastname($lastname) { @@ -1501,7 +1502,7 @@ public function setLastname($lastname) } /** - * {@inheritdoc} + * @inheritdoc */ public function getMiddlename() { @@ -1509,7 +1510,7 @@ public function getMiddlename() } /** - * {@inheritdoc} + * @inheritdoc */ public function setMiddlename($middlename) { @@ -1517,7 +1518,7 @@ public function setMiddlename($middlename) } /** - * {@inheritdoc} + * @inheritdoc */ public function getPrefix() { @@ -1525,7 +1526,7 @@ public function getPrefix() } /** - * {@inheritdoc} + * @inheritdoc */ public function setPrefix($prefix) { @@ -1533,7 +1534,7 @@ public function setPrefix($prefix) } /** - * {@inheritdoc} + * @inheritdoc */ public function getSuffix() { @@ -1541,7 +1542,7 @@ public function getSuffix() } /** - * {@inheritdoc} + * @inheritdoc */ public function setSuffix($suffix) { @@ -1549,7 +1550,7 @@ public function setSuffix($suffix) } /** - * {@inheritdoc} + * @inheritdoc */ public function getVatId() { @@ -1557,7 +1558,7 @@ public function getVatId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatId($vatId) { @@ -1565,7 +1566,7 @@ public function setVatId($vatId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCustomerId() { @@ -1573,7 +1574,7 @@ public function getCustomerId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomerId($customerId) { @@ -1581,7 +1582,7 @@ public function setCustomerId($customerId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getEmail() { @@ -1594,7 +1595,7 @@ public function getEmail() } /** - * {@inheritdoc} + * @inheritdoc */ public function setEmail($email) { @@ -1602,7 +1603,7 @@ public function setEmail($email) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegion($region) { @@ -1610,7 +1611,7 @@ public function setRegion($region) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegionId($regionId) { @@ -1618,7 +1619,7 @@ public function setRegionId($regionId) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegionCode($regionCode) { @@ -1626,7 +1627,7 @@ public function setRegionCode($regionCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getSameAsBilling() { @@ -1634,7 +1635,7 @@ public function getSameAsBilling() } /** - * {@inheritdoc} + * @inheritdoc */ public function setSameAsBilling($sameAsBilling) { @@ -1642,7 +1643,7 @@ public function setSameAsBilling($sameAsBilling) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCustomerAddressId() { @@ -1650,7 +1651,7 @@ public function getCustomerAddressId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomerAddressId($customerAddressId) { @@ -1681,9 +1682,7 @@ public function setSaveInAddressBook($saveInAddressBook) //@codeCoverageIgnoreEnd /** - * {@inheritdoc} - * - * @return \Magento\Quote\Api\Data\AddressExtensionInterface|null + * @inheritdoc */ public function getExtensionAttributes() { @@ -1691,10 +1690,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} - * - * @param \Magento\Quote\Api\Data\AddressExtensionInterface $extensionAttributes - * @return $this + * @inheritdoc */ public function setExtensionAttributes(\Magento\Quote\Api\Data\AddressExtensionInterface $extensionAttributes) { @@ -1712,7 +1708,7 @@ public function getShippingMethod() } /** - * {@inheritdoc} + * @inheritdoc */ protected function getCustomAttributesCodes() { From 14d9528852bd30b6f7545b3a22ac2d555a196543 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Fri, 21 Sep 2018 15:14:11 -0300 Subject: [PATCH 085/812] Replaced {@inheritdoc} with the actual documentation in order to fix code style violations --- .../Framework/Stdlib/DateTime/Timezone.php | 71 +++++++++++++++---- .../Stdlib/DateTime/TimezoneInterface.php | 18 ++++- 2 files changed, 74 insertions(+), 15 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 59b299d176bd1..2bfa465c8268f 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -85,7 +85,9 @@ public function __construct( } /** - * {@inheritdoc} + * Return path to default timezone + * + * @return string */ public function getDefaultTimezonePath() { @@ -93,7 +95,9 @@ public function getDefaultTimezonePath() } /** - * {@inheritdoc} + * Retrieve timezone code + * + * @return string */ public function getDefaultTimezone() { @@ -101,7 +105,11 @@ public function getDefaultTimezone() } /** - * {@inheritdoc} + * Gets the scope config timezone + * + * @param string $scopeType + * @param string $scopeCode + * @return string */ public function getConfigTimezone($scopeType = null, $scopeCode = null) { @@ -113,7 +121,10 @@ public function getConfigTimezone($scopeType = null, $scopeCode = null) } /** - * {@inheritdoc} + * Retrieve ISO date format + * + * @param int $type + * @return string */ public function getDateFormat($type = \IntlDateFormatter::SHORT) { @@ -125,7 +136,9 @@ public function getDateFormat($type = \IntlDateFormatter::SHORT) } /** - * {@inheritdoc} + * Retrieve short date format with 4-digit year + * + * @return string */ public function getDateFormatWithLongYear() { @@ -137,7 +150,10 @@ public function getDateFormatWithLongYear() } /** - * {@inheritdoc} + * Retrieve ISO time format + * + * @param string $type + * @return string */ public function getTimeFormat($type = \IntlDateFormatter::SHORT) { @@ -149,7 +165,10 @@ public function getTimeFormat($type = \IntlDateFormatter::SHORT) } /** - * {@inheritdoc} + * Retrieve ISO datetime format + * + * @param string $type + * @return string */ public function getDateTimeFormat($type) { @@ -157,7 +176,13 @@ public function getDateTimeFormat($type) } /** - * {@inheritdoc} + * Create \DateTime object for current locale + * + * @param mixed $date + * @param string $locale + * @param bool $useTimezone + * @param bool $includeTime + * @return \DateTime */ public function date($date = null, $locale = null, $useTimezone = true, $includeTime = true) { @@ -191,7 +216,12 @@ public function date($date = null, $locale = null, $useTimezone = true, $include } /** - * {@inheritdoc} + * Create \DateTime object with date converted to scope timezone and scope Locale + * + * @param mixed $scope Information about scope + * @param string|integer|\DateTime|array|null $date date in UTC + * @param boolean $includeTime flag for including time to date + * @return \DateTime */ public function scopeDate($scope = null, $date = null, $includeTime = false) { @@ -204,7 +234,12 @@ public function scopeDate($scope = null, $date = null, $includeTime = false) } /** - * {@inheritdoc} + * Format date using current locale options and time zone. + * + * @param \DateTime|null $date + * @param int $format + * @param bool $showTime + * @return string */ public function formatDate($date = null, $format = \IntlDateFormatter::SHORT, $showTime = false) { @@ -218,7 +253,12 @@ public function formatDate($date = null, $format = \IntlDateFormatter::SHORT, $s } /** - * {@inheritdoc} + * Get scope timestamp + * + * Timestamp will be built with scope timezone settings + * + * @param mixed $scope + * @return int */ public function scopeTimeStamp($scope = null) { @@ -231,7 +271,12 @@ public function scopeTimeStamp($scope = null) } /** - * {@inheritdoc} + * Checks if current date of the given scope (in the scope timezone) is within the range + * + * @param int|string|\Magento\Framework\App\ScopeInterface $scope + * @param string|null $dateFrom + * @param string|null $dateTo + * @return bool */ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) { @@ -300,6 +345,7 @@ public function formatDateTime( /** * Convert date from config timezone to Utc. + * * If pass \DateTime object as argument be sure that timezone is the same with config timezone * * @param string|\DateTimeInterface $date @@ -315,6 +361,7 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') /** * Convert date from config timezone to Utc. + * * If pass \DateTime object as argument be sure that timezone is the same with config timezone * * @param string|\DateTimeInterface $date diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index 5a4b15d6cca0c..17ba759a4d763 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -80,6 +80,7 @@ public function scopeDate($scope = null, $date = null, $includeTime = false); /** * Get scope timestamp + * * Timestamp will be built with scope timezone settings * * @param mixed $scope @@ -121,6 +122,7 @@ public function getConfigTimezone($scopeType = null, $scopeCode = null); public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null); /** + * * @param string|\DateTimeInterface $date * @param int $dateType * @param int $timeType @@ -139,19 +141,29 @@ public function formatDateTime( ); /** + * Convert date from config timezone to Utc. + * + * If pass \DateTime object as argument be sure that timezone is the same with config timezone + * * @param string|\DateTimeInterface $date * @param string $format + * @throws LocalizedException * @return string - * @since 100.1.0 * @deprecated */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s'); /** - * @param $date + * Convert date from config timezone to Utc. + * + * If pass \DateTime object as argument be sure that timezone is the same with config timezone + * + * @param string|\DateTimeInterface $date * @param string $format * @param string $pattern - * @return mixed + * @throws LocalizedException + * @return string + * @deprecated */ public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = 'Y-m-d H:i:s'); } From 93f6e5e17d024e00cea0bcf6254afc47cf53b73a Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Sat, 22 Sep 2018 11:46:44 +0200 Subject: [PATCH 086/812] Added schema concept for working with cart addresses and shipping methods --- .../Magento/QuoteGraphQl/etc/schema.graphqls | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 06b3328b9e058..b10575171781e 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -1,10 +1,82 @@ # Copyright © Magento, Inc. All rights reserved. # See COPYING.txt for license details. +type Query { + getAvailableShippingMethodsOnCart(input: AvailableShippingMethodsOnCartInput): AvailableShippingMethodsOnCartOutput @doc(description:"Returns available shipping methods for cart by address/address_id") +} + type Mutation { createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") + setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput + setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput + setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput +} + +input SetShippingAddressesOnCartInput { + cart_id: String! + customer_address_id: Int # Can be provided in one-page checkout and is required for multi-shipping checkout + address: CartAddressInput + cart_items: [CartItemQuantityInput!] +} + +input CartItemQuantityInput { + cart_item_id: Int! + quantity: Float! +} + +input SetBillingAddressOnCartInput { + cart_id: String! + customer_address_id: Int + address: CartAddressInput + # TODO: consider adding "Same as shipping" option +} + +input CartAddressInput { + firstname: String! + lastname: String! + company: String + street: [String!]! + city: String! + region: String + postcode: String + country_code: String! + telephone: String! + save_in_address_book: Boolean! +} + +input SetShippingMethodsOnCartInput { + shipping_methods: [ShippingMethodForAddressInput!]! +} + +input ShippingMethodForAddressInput { + cart_address_id: String! + shipping_method_code: String! +} + +type SetBillingAddressOnCartOutput { + cart: Cart! +} + +type SetShippingAddressesOnCartOutput { + cart: Cart! +} + +type SetShippingMethodsOnCartOutput { + cart: Cart! +} + +# If no address is provided, the system get address assigned to a quote +# If there's no address at all - the system returns all shipping methods +type AvailableShippingMethodsOnCartInput { + cart_id: String! + customer_address_id: Int + address: CartAddressInput +} + +type AvailableShippingMethodsOnCartOutput { + available_shipping_methods: [CheckoutShippingMethod] } input ApplyCouponToCartInput { @@ -18,12 +90,56 @@ type ApplyCouponToCartOutput { type Cart { applied_coupon: AppliedCoupon + addresses: [CartAddress]! } type CartAddress { + firstname: String! + lastname: String! + company: String + street: [String!]! + city: String! + region: CartAddressRegion + postcode: String + country: CartAddressCountry! + telephone: String! + address_type: AdressTypeEnum! + selected_shipping_method: CheckoutShippingMethod + available_shipping_methods: [CheckoutShippingMethod]! + items_weight: Float + customer_notes: String + cart_items: [CartItemQuantity] applied_coupon: AppliedCoupon } +type CartItemQuantity { + cart_item_id: String! + quantity: Float! +} + +type CartAddressRegion { + code: String + label: String +} + +type CartAddressCountry { + code: String + label: String +} + +type CheckoutShippingMethod { + code: String + label: String + free_shipping: Boolean! + error_message: String + # TODO: Add more complex structure for shipping rates +} + +enum AdressTypeEnum { + SHIPPING + BILLING +} + type AppliedCoupon { code: String! } From 79a968ba6bbb54ce8c3e5714bba164f924fc74f3 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Sat, 22 Sep 2018 10:28:58 +0000 Subject: [PATCH 087/812] graphQl-44: refactoring of format strategy Signed-off-by: vitaliyboyko <v.boyko@atwix.com> --- .../Resolver/Product/ProductTextAttribute.php | 33 +++++++++---------- .../ProductTextAttribute/FormatInterface.php | 2 +- .../ProductTextAttribute/FormatList.php | 28 +++++++++------- .../Product/ProductTextAttribute/Html.php | 2 +- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 7 ++++ .../CatalogGraphQl/etc/schema.graphqls | 12 +++---- 6 files changed, 46 insertions(+), 38 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php index f04609f91c86d..9c1212667acf3 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -8,7 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Catalog\Model\Product; -use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\FormatFactory; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\FormatList; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; @@ -18,9 +18,12 @@ /** * Resolve rendered content for attributes where HTML content is allowed */ -class ProductTextareaAttribute implements ResolverInterface +class ProductTextAttribute implements ResolverInterface { - const DEFAULT_CONTENT_FORMAT_IDENTIFIER = 'html'; + /** + * @var FormatList + */ + private $formatList; /** * @var ValueFactory @@ -28,20 +31,20 @@ class ProductTextareaAttribute implements ResolverInterface private $valueFactory; /** - * @var FormatFactory + * @var string */ - private $formatFactory; + private $defaultFormat = 'html'; /** * @param ValueFactory $valueFactory - * @param FormatFactory $formatFactory + * @param FormatList $formatFactory */ public function __construct( ValueFactory $valueFactory, - FormatFactory $formatFactory + FormatList $formatFactory ) { $this->valueFactory = $valueFactory; - $this->formatFactory = $formatFactory; + $this->formatList = $formatFactory; } /** @@ -55,22 +58,16 @@ public function resolve( array $args = null ): Value { if (!isset($value['model'])) { - $result = function () { - return null; - }; + $result = []; return $this->valueFactory->create($result); } /* @var $product Product */ $product = $value['model']; $fieldName = $field->getName(); - $formatIdentifier = $args['format'] ?? self::DEFAULT_CONTENT_FORMAT_IDENTIFIER; - $format = $this->formatFactory->create($formatIdentifier); - $attribute = ['content' => $format->getContent($product, $fieldName)]; - - $result = function () use ($attribute) { - return $attribute; - }; + $formatIdentifier = $args['format'] ?? $this->defaultFormat; + $format = $this->formatList->create($formatIdentifier); + $result = ['content' => $format->getContent($product, $fieldName)]; return $this->valueFactory->create($result); } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php index fae685b75c060..2cf702bf18466 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute; +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; use Magento\Catalog\Model\Product as ModelProduct; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php index 97e0be3763f1d..2e2f21d643092 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php @@ -9,35 +9,39 @@ use Magento\Framework\ObjectManagerInterface; -class FormatFactory +class FormatList { /** * @var ObjectManagerInterface */ private $objectManager; + /** + * @var string + */ + private $formats; + /** * @param ObjectManagerInterface $objectManager + * @param array $formats */ - public function __construct(ObjectManagerInterface $objectManager) - { + public function __construct( + ObjectManagerInterface $objectManager, + array $formats + ) { $this->objectManager = $objectManager; + $this->formats = $formats; } /** * @param string $formatIdentifier - * @param array $data * @return FormatInterface */ - public function create(string $formatIdentifier, $data = []) : FormatInterface + public function create(string $formatIdentifier) : FormatInterface { - $formatClassName = 'Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\\' . ucfirst($formatIdentifier); - $formatInstance = $this->objectManager->create($formatClassName, $data); - if (false == $formatInstance instanceof FormatInterface) { - throw new \InvalidArgumentException( - $formatInstance . ' is not instance of \Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute\FormatInterface' - ); - } + $formatClassName = 'Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\\' . ucfirst($formatIdentifier); + $formatInstance = $this->objectManager->get($formatClassName); + return $formatInstance; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php index 8201c40427dc9..75c29a3f78fac 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextareaAttribute; +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; use Magento\Catalog\Helper\Output as OutputHelper; diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 68a292ede6b4a..8d4ca97001d3d 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -63,6 +63,13 @@ <argument name="collectionProcessor" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor</argument> </arguments> </type> + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\FormatList"> + <arguments> + <argument name="formats" xsi:type="array"> + <item name="html" xsi:type="string">Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\Html</item> + </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"> diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index a9c4a1b4bd8ae..3f3282ed5f529 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextareaAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: ProductTextareaAttribute @doc(description: "A short description of the product. Its use depends on the theme.") + description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -552,9 +552,9 @@ type SortFields @doc(description: "SortFields contains a default value for sort options: [SortField] @doc(description: "Available sort fields") } -type ProductTextareaAttribute { +type ProductTextAttribute { content ( - format: String! @doc(description: "The format of content") -): String - @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextareaAttribute") + format: String @doc(description: "The format of content") +): String @doc(description: "The format of content") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") } From e327bb695bf2cb01240d5d442d5d269fb3c50064 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Sat, 22 Sep 2018 15:18:18 +0000 Subject: [PATCH 088/812] graphQl: shipping address concept Signed-off-by: vitaliyboyko <v.boyko@atwix.com> --- .../SetShippingAddressesOnCart.php | 104 ++++++++++++++++++ .../Magento/QuoteGraphQl/etc/schema.graphqls | 2 +- 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php new file mode 100644 index 0000000000000..9d54792136367 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php @@ -0,0 +1,104 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress; + +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Framework\Api\DataObjectHelper; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; +use Magento\Quote\Model\Quote\Address; +use Magento\Quote\Model\ShippingAddressManagementInterface; + +/** + * @inheritdoc + */ +class SetShippingAddressesOnCart implements ResolverInterface +{ + /** + * @var ShippingAddressManagementInterface + */ + private $shippingAddressManagement; + + /** + * @var AddressRepositoryInterface + */ + private $addressRepository; + + /** + * @var Address + */ + private $addressModel; + /** + * @var DataObjectHelper + */ + private $dataObjectHelper; + + /** + * @var MaskedQuoteIdToQuoteIdInterface + */ + private $maskedQuoteIdToQuoteId; + + /** + * @param ShippingAddressManagementInterface $shippingAddressManagement + * @param AddressRepositoryInterface $addressRepository + * @param Address $addressModel + * @param DataObjectHelper $dataObjectHelper + * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + */ + public function __construct( + ShippingAddressManagementInterface $shippingAddressManagement, + AddressRepositoryInterface $addressRepository, + Address $addressModel, + DataObjectHelper $dataObjectHelper, + MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + ) { + $this->shippingAddressManagement = $shippingAddressManagement; + $this->addressRepository = $addressRepository; + $this->addressModel = $addressModel; + $this->dataObjectHelper = $dataObjectHelper; + $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + if (!isset($args['input']['cart_id'])) { + throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); + } + $maskedCartId = $args['input']['cart_id']; + $cartId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); + + $customerAddressId = $args['input']['customer_address_id'] ?? 0; + $address = $args['input']['address'] ?? null; + $cartItems = $args['input']['cart_items'] ?? []; + + if (!$customerAddressId && !$address) { + throw new GraphQlInputException(__('Query should contain either address id or address input.')); + } + + if (!$cartItems) { + if($customerAddressId) { + $customerAddress = $this->addressRepository->getById($customerAddressId); + $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); + $this->shippingAddressManagement->assign($cartId, $shippingAddress); + } else { + $shippingAddress = $this->addressModel->addData($address); + $this->shippingAddressManagement->assign($cartId, $shippingAddress); + } + } else { + //TODO: implement multi shipping address assign flow + } + + return []; + } +} diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index b10575171781e..d13240a23140b 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -9,7 +9,7 @@ type Mutation { createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") - setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput + setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ShippingAddress\\SetShippingAddressesOnCart") setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput } From 18f78d5c5b1a760813647b794e5365dfe885367e Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Mon, 24 Sep 2018 15:26:43 +0300 Subject: [PATCH 089/812] MAGETWO-91725: Reward Points Balance Update Emails are not being sent when balance change initiated by store front - Fixed an issue with incorrect work of 'Subscribe for Balance Updates' functionality; --- .../Model/Metadata/CustomerMetadata.php | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php b/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php index 7ed806e657e82..7e8f0b9236fe9 100644 --- a/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php +++ b/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php @@ -46,7 +46,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getAttributes($formCode) { @@ -67,7 +67,7 @@ public function getAttributes($formCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getAttributeMetadata($attributeCode) { @@ -92,7 +92,7 @@ public function getAttributeMetadata($attributeCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getAllAttributesMetadata() { @@ -116,7 +116,7 @@ public function getAllAttributesMetadata() } /** - * {@inheritdoc} + * @inheritdoc */ public function getCustomAttributesMetadata($dataObjectClassName = self::DATA_INTERFACE_NAME) { @@ -134,13 +134,27 @@ public function getCustomAttributesMetadata($dataObjectClassName = self::DATA_IN $isDataObjectMethod = isset($this->customerDataObjectMethods['get' . $camelCaseKey]) || isset($this->customerDataObjectMethods['is' . $camelCaseKey]); - /** Even though disable_auto_group_change is system attribute, it should be available to the clients */ if (!$isDataObjectMethod - && (!$attributeMetadata->isSystem() || $attributeCode == 'disable_auto_group_change') + && (!$attributeMetadata->isSystem() + || in_array($attributeCode, $this->getAllowedSystemAttributesList()) + ) ) { $customAttributes[] = $attributeMetadata; } } return $customAttributes; } + + /** + * Get list of system attributes which should be available to the clients + * + * @return array + */ + private function getAllowedSystemAttributesList() + { + return [ + 'disable_auto_group_change', + 'reward_update_notification' + ]; + } } From aef18a56e212eb0f55c5393c5a814b6bb15c9510 Mon Sep 17 00:00:00 2001 From: Aleksey Tsoy <aleksey_tsoy@epam.com> Date: Mon, 24 Sep 2018 19:04:00 +0600 Subject: [PATCH 090/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Added automated test --- .../StorefrontCategoryActionGroup.xml | 15 +++ .../Mftf/Data/CatalogStorefrontConfigData.xml | 41 ++++++ .../Metadata/catalog_configuration-meta.xml | 118 ++++++++++++++++++ .../Section/StorefrontCategoryMainSection.xml | 3 + ...orefrontRememberCategoryPaginationTest.xml | 68 ++++++++++ 5 files changed, 245 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_configuration-meta.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/StorefrontRememberCategoryPaginationTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml index c980c43b8f3af..e215aa81b3384 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml @@ -21,6 +21,21 @@ <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> + <actionGroup name="VerifyCategoryPageParameters"> + <arguments> + <argument name="category"/> + <argument name="mode" type="string"/> + <argument name="numOfProductsPerPage" type="string"/> + <argument name="sortBy" type="string" defaultValue="position"/> + </arguments> + <seeInCurrentUrl url="/{{category.custom_attributes[url_key]}}.html" stepKey="checkUrl"/> + <seeInTitle userInput="{{category.name}}" stepKey="assertCategoryNameInTitle"/> + <see userInput="{{category.name}}" selector="{{StorefrontCategoryMainSection.CategoryTitle}}" stepKey="assertCategoryName"/> + <see userInput="{{mode}}" selector="{{StorefrontCategoryMainSection.modeGridIsActive}}" stepKey="assertViewMode"/> + <see userInput="{{numOfProductsPerPage}}" selector="{{StorefrontCategoryMainSection.perPage}}" stepKey="assertNumberOfProductsPerPage"/> + <see userInput="{{sortBy}}" selector="{{StorefrontCategoryMainSection.sortedBy}}" stepKey="assertSortedBy"/> + </actionGroup> + <!-- Check the category page --> <actionGroup name="StorefrontCheckCategoryActionGroup"> <arguments> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml new file mode 100644 index 0000000000000..d8ec84013d93b --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml @@ -0,0 +1,41 @@ +<?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="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="RememberPaginationCatalogStorefrontConfig" type="catalog_storefront_config"> + <requiredEntity type="grid_per_page_values">GridPerPageValues</requiredEntity> + <requiredEntity type="remember_pagination">RememberCategoryPagination</requiredEntity> + </entity> + + <entity name="GridPerPageValues" type="grid_per_page_values"> + <data key="value">9,12,20,24</data> + </entity> + + <entity name="RememberCategoryPagination" type="remember_pagination"> + <data key="value">1</data> + </entity> + + <entity name="DefaultCatalogStorefrontConfiguration" type="default_catalog_storefront_config"> + <requiredEntity type="catalogStorefrontFlagZero">DefaultCatalogStorefrontFlagZero</requiredEntity> + <data key="list_allow_all">DefaultListAllowAll</data> + <data key="flat_catalog_product">DefaultFlatCatalogProduct</data> + </entity> + + <entity name="DefaultCatalogStorefrontFlagZero" type="catalogStorefrontFlagZero"> + <data key="value">0</data> + </entity> + + <entity name="DefaultListAllowAll" type="list_allow_all"> + <data key="value">0</data> + </entity> + + <entity name="DefaultFlatCatalogProduct" type="flat_catalog_product"> + <data key="value">0</data> + </entity> +</entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_configuration-meta.xml b/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_configuration-meta.xml new file mode 100644 index 0000000000000..b1f2b43220b36 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_configuration-meta.xml @@ -0,0 +1,118 @@ +<?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="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> + <operation name="CatalogStorefrontConfiguration" dataType="catalog_storefront_config" type="create" auth="adminFormKey" url="/admin/system_config/save/section/catalog/" method="POST"> + <object key="groups" dataType="catalog_storefront_config"> + <object key="frontend" dataType="catalog_storefront_config"> + <object key="fields" dataType="catalog_storefront_config"> + <object key="list_mode" dataType="list_mode"> + <field key="value">string</field> + </object> + <object key="grid_per_page_values" dataType="grid_per_page_values"> + <field key="value">string</field> + </object> + <object key="grid_per_page" dataType="grid_per_page"> + <field key="value">string</field> + </object> + <object key="list_per_page_values" dataType="list_per_page_values"> + <field key="value">string</field> + </object> + <object key="list_per_page" dataType="list_per_page"> + <field key="value">string</field> + </object> + <object key="default_sort_by" dataType="default_sort_by"> + <field key="value">string</field> + </object> + <object key="list_allow_all" dataType="list_allow_all"> + <field key="value">integer</field> + </object> + <object key="remember_pagination" dataType="remember_pagination"> + <field key="value">integer</field> + </object> + <object key="flat_catalog_category" dataType="flat_catalog_category"> + <field key="value">integer</field> + </object> + <object key="flat_catalog_product" dataType="flat_catalog_product"> + <field key="value">integer</field> + </object> + <object key="swatches_per_product" dataType="swatches_per_product"> + <field key="value">string</field> + </object> + <object key="show_swatches_in_product_list" dataType="show_swatches_in_product_list"> + <field key="value">integer</field> + </object> + </object> + </object> + </object> + </operation> + + <operation name="DefaultCatalogStorefrontConfiguration" dataType="default_catalog_storefront_config" type="create" auth="adminFormKey" url="/admin/system_config/save/section/catalog/" method="POST"> + <object key="groups" dataType="default_catalog_storefront_config"> + <object key="frontend" dataType="default_catalog_storefront_config"> + <object key="fields" dataType="default_catalog_storefront_config"> + <object key="list_mode" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="grid_per_page_values" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="grid_per_page" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="list_per_page_values" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="list_per_page" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="default_sort_by" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="remember_pagination" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="flat_catalog_category" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="swatches_per_product" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="show_swatches_in_product_list" dataType="default_catalog_storefront_config"> + <object key="inherit" dataType="catalogStorefrontFlagZero"> + <field key="value">integer</field> + </object> + </object> + <object key="list_allow_all" dataType="list_allow_all"> + <field key="value">integer</field> + </object> + <object key="flat_catalog_product" dataType="flat_catalog_product"> + <field key="value">integer</field> + </object> + </object> + </object> + </object> + </operation> +</operations> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml index d484abf2069ff..03566be55ad2f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml @@ -9,6 +9,9 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="StorefrontCategoryMainSection"> + <element name="perPage" type="select" selector="//*[@id='authenticationPopup']/following-sibling::div[3]//*[@id='limiter']"/> + <element name="sortedBy" type="select" selector="//*[@id='authenticationPopup']/following-sibling::div[1]//*[@id='sorter']"/> + <element name="modeGridIsActive" type="text" selector="//*[@id='authenticationPopup']/following-sibling::div[1]//*[@class='modes']/strong[@class='modes-mode active mode-grid']/span"/> <element name="modeListButton" type="button" selector="#mode-list"/> <element name="CategoryTitle" type="text" selector="#page-title-heading span"/> <element name="ProductItemInfo" type="button" selector=".product-item-info"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontRememberCategoryPaginationTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontRememberCategoryPaginationTest.xml new file mode 100644 index 0000000000000..0ed61b8636c4f --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontRememberCategoryPaginationTest.xml @@ -0,0 +1,68 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontRememberCategoryPaginationTest"> + <annotations> + <title value="Verify that Number of Products per page retained when visiting a different category"/> + <stories value="MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category"/> + <description value="Verify that Number of Products per page retained when visiting a different category"/> + <features value="Catalog"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94210"/> + <group value="Catalog"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="defaultCategory1"/> + <createData entity="SimpleProduct" stepKey="simpleProduct1"> + <requiredEntity createDataKey="defaultCategory1"/> + </createData> + + <createData entity="_defaultCategory" stepKey="defaultCategory2"/> + <createData entity="SimpleProduct" stepKey="simpleProduct2"> + <requiredEntity createDataKey="defaultCategory2"/> + </createData> + + <createData entity="RememberPaginationCatalogStorefrontConfig" stepKey="setRememberPaginationCatalogStorefrontConfig"/> + </before> + + <actionGroup ref="GoToStorefrontCategoryPageByParameters" stepKey="GoToStorefrontCategory1Page"> + <argument name="category" value="$$defaultCategory1.custom_attributes[url_key]$$"/> + <argument name="mode" value="grid"/> + <argument name="numOfProductsPerPage" value="12"/> + </actionGroup> + + <actionGroup ref="VerifyCategoryPageParameters" stepKey="verifyCategory1PageParameters"> + <argument name="category" value="$$defaultCategory1$$"/> + <argument name="mode" value="grid"/> + <argument name="numOfProductsPerPage" value="12"/> + </actionGroup> + + <amOnPage url="{{StorefrontCategoryPage.url($$defaultCategory2.name$$)}}" stepKey="navigateToCategory2Page"/> + <waitForPageLoad stepKey="waitForCategory2PageToLoad"/> + + <actionGroup ref="VerifyCategoryPageParameters" stepKey="verifyCategory2PageParameters"> + <argument name="category" value="$$defaultCategory2$$"/> + <argument name="mode" value="grid"/> + <argument name="numOfProductsPerPage" value="12"/> + </actionGroup> + + <after> + <createData entity="DefaultCatalogStorefrontConfiguration" stepKey="setDefaultCatalogStorefrontConfiguration"/> + + <deleteData createDataKey="simpleProduct1" stepKey="deleteProduct1"/> + <deleteData createDataKey="defaultCategory1" stepKey="deleteCategory1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteProduct2"/> + <deleteData createDataKey="defaultCategory2" stepKey="deleteCategory2"/> + + <magentoCLI command="cache:flush" stepKey="flushCache"/> + + </after> + </test> +</tests> From 160f0879e39e39a6baa48723c05255c0fc37c860 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Mon, 24 Sep 2018 16:48:01 +0300 Subject: [PATCH 091/812] MAGETWO-91707: [Sigma Beauty]Cannot pause Youtube video in IE 11 - Fix added --- lib/web/fotorama/fotorama.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/web/fotorama/fotorama.js b/lib/web/fotorama/fotorama.js index 89cb315b0d2c4..4bfa2f12d5248 100644 --- a/lib/web/fotorama/fotorama.js +++ b/lib/web/fotorama/fotorama.js @@ -2487,11 +2487,11 @@ fotoramaVersion = '4.6.4'; .append($videoPlay.clone()); // This solves tabbing problems - addFocus(frame, function () { + addFocus(frame, function (e) { setTimeout(function () { lockScroll($stage); }, 0); - clickToShow({index: frameData.eq, user: true}); + clickToShow({index: frameData.eq, user: true}, e); }); $stageFrame = $stageFrame.add($frame); @@ -3040,7 +3040,10 @@ fotoramaVersion = '4.6.4'; return time; } - that.showStage = function (silent, options, time) { + that.showStage = function (silent, options, time, e) { + if (e !== undefined && e.target.tagName == 'IFRAME') { + return; + } unloadVideo($videoPlaying, activeFrame.i !== data[normalizeIndex(repositionIndex)].i); frameDraw(activeIndexes, 'stage'); stageFramePosition(SLOW ? [dirtyIndex] : [dirtyIndex, getPrevIndex(dirtyIndex), getNextIndex(dirtyIndex)]); @@ -3128,7 +3131,7 @@ fotoramaVersion = '4.6.4'; } }; - that.show = function (options) { + that.show = function (options, e) { that.longPress.singlePressInProgress = true; var index = calcActiveIndex(options); @@ -3139,7 +3142,7 @@ fotoramaVersion = '4.6.4'; var silent = _activeFrame === activeFrame && !options.user; - that.showStage(silent, options, time); + that.showStage(silent, options, time, e); that.showNav(silent, options, time); showedFLAG = typeof lastActiveIndex !== 'undefined' && lastActiveIndex !== activeIndex; @@ -3499,7 +3502,7 @@ fotoramaVersion = '4.6.4'; $stage.on('mousemove', stageCursor); - function clickToShow(showOptions) { + function clickToShow(showOptions, e) { clearTimeout(clickToShow.t); if (opts.clicktransition && opts.clicktransition !== opts.transition) { @@ -3516,7 +3519,7 @@ fotoramaVersion = '4.6.4'; }, 10); }, 0); } else { - that.show(showOptions); + that.show(showOptions, e); } } From b4bb58cfd3e0c33c96b4100ea84ba30197ad7c23 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Mon, 24 Sep 2018 16:59:40 +0300 Subject: [PATCH 092/812] MAGETWO-91657: Advanced pricing the bulk discounts by percentage returns error when set - Added new validation rule for percentage value; --- .../Product/Form/Modifier/TierPrice.php | 4 +--- .../view/base/web/js/lib/validation/rules.js | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php index 5f8d7fcf9049a..1f0da62f61056 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php @@ -154,9 +154,7 @@ private function getUpdatedTierPriceStructure(array $priceMeta) 'addbefore' => '%', 'validation' => [ 'required-entry' => true, - 'validate-number' => true, - 'validate-greater-than-zero' => true, - 'less-than-equals-to' => 100 + 'validate-positive-percent-decimal' => true ], 'visible' => $firstOption && $firstOption['value'] == ProductPriceOptionsInterface::VALUE_PERCENT, diff --git a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js index 74f696f3f2a24..1c647bed2ea7b 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js @@ -686,6 +686,24 @@ define([ }, $.mage.__('The value is not within the specified range.') ], + 'validate-positive-percent-decimal': [ + function (value) { + var numValue; + + if (utils.isEmptyNoTrim(value) || !/^\s*-?\d*(\.\d*)?\s*$/.test(value)) { + return false; + } + + numValue = utils.parseNumber(value); + + if (isNaN(numValue)) { + return false; + } + + return utils.isBetween(numValue, 0.01, 100); + }, + $.mage.__('Please enter a valid percentage discount value greater than 0.') + ], 'validate-digits': [ function (value) { return utils.isEmptyNoTrim(value) || !/[^\d]/.test(value); From 68933c1b128f09b74298f81822879e2bee63d68a Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <mikalai_shostka@epam.com> Date: Mon, 24 Sep 2018 17:35:47 +0300 Subject: [PATCH 093/812] MAGETWO-70303: [GITHUB] Anchor categories are showing products of disabled subcategories #9002 - Change index table and temporary table --- .../Category/Product/AbstractAction.php | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php index 6a499883ac723..d312b78e74059 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php @@ -499,7 +499,7 @@ protected function createAnchorSelect(Store $store) 'cc2.parent_id = cc.entity_id AND cc.entity_id NOT IN (' . implode( ',', $rootCatIds - ) . ')', + ) . ') AND cc2.store_id = ' . $store->getId(), [] )->joinInner( ['ccp' => $this->getTable('catalog_category_product')], @@ -586,6 +586,8 @@ protected function createAnchorSelect(Store $store) } /** + * Get temporary table name + * * Get temporary table name for concurrent indexing in persistent connection * Temp table name is NOT shared between action instances and each action has it's own temp tree index * @@ -629,6 +631,12 @@ protected function makeTempCategoryTreeIndex() null, ['nullable' => false, 'unsigned' => true] ); + $temporaryTable->addColumn( + 'store_id', + \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + null, + ['nullable' => false, 'unsigned' => true] + ); // Each entry will be unique. $temporaryTable->addIndex( 'idx_primary', @@ -642,6 +650,11 @@ protected function makeTempCategoryTreeIndex() ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX] ); + $temporaryTable->addIndex( + 'store_id', + ['store_id'], + ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX] + ); // Drop the temporary table in case it already exists on this (persistent?) connection. $this->connection->dropTemporaryTable($temporaryName); $this->connection->createTemporaryTable($temporaryTable); @@ -659,11 +672,23 @@ protected function makeTempCategoryTreeIndex() */ protected function fillTempCategoryTreeIndex($temporaryName) { + $isActiveAttributeId = $this->config->getAttribute( + \Magento\Catalog\Model\Category::ENTITY, + 'is_active' + )->getId(); + $categoryMetadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\CategoryInterface::class); + $categoryLinkField = $categoryMetadata->getLinkField(); $selects = $this->prepareSelectsByRange( $this->connection->select() ->from( ['c' => $this->getTable('catalog_category_entity')], ['entity_id', 'path'] + )->joinInner( + ['ccei' => $this->getTable('catalog_category_entity_int')], + 'ccei.' . $categoryLinkField . ' = c.' . $categoryLinkField . + ' AND ccei.attribute_id = ' . $isActiveAttributeId . + ' AND ccei.value = 1', + ['store_id'] ), 'entity_id' ); @@ -674,13 +699,13 @@ protected function fillTempCategoryTreeIndex($temporaryName) foreach ($this->connection->fetchAll($select) as $category) { foreach (explode('/', $category['path']) as $parentId) { if ($parentId !== $category['entity_id']) { - $values[] = [$parentId, $category['entity_id']]; + $values[] = [$parentId, $category['entity_id'], $category['store_id']]; } } } if (count($values) > 0) { - $this->connection->insertArray($temporaryName, ['parent_id', 'child_id'], $values); + $this->connection->insertArray($temporaryName, ['parent_id', 'child_id', 'store_id'], $values); } } } From 5a38724d165ffd0c325d015cffaf7732834b7157 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Mon, 24 Sep 2018 20:00:27 +0300 Subject: [PATCH 094/812] MAGETWO-91650: Translation not working for product alerts - Add store id for product alert --- .../ProductAlert/Controller/Add/Price.php | 16 +++--- .../ProductAlert/Controller/Add/Stock.php | 28 ++++++++--- app/code/Magento/ProductAlert/Model/Email.php | 49 +++++++++++++------ .../Magento/ProductAlert/Model/Observer.php | 19 +++++++ app/code/Magento/ProductAlert/Model/Price.php | 10 ++++ app/code/Magento/ProductAlert/Model/Stock.php | 10 ++++ .../Magento/ProductAlert/etc/db_schema.xml | 16 ++++++ .../ProductAlert/etc/db_schema_whitelist.json | 20 +++++--- 8 files changed, 133 insertions(+), 35 deletions(-) diff --git a/app/code/Magento/ProductAlert/Controller/Add/Price.php b/app/code/Magento/ProductAlert/Controller/Add/Price.php index 04e623105e645..fbaff109fd15a 100644 --- a/app/code/Magento/ProductAlert/Controller/Add/Price.php +++ b/app/code/Magento/ProductAlert/Controller/Add/Price.php @@ -6,6 +6,7 @@ namespace Magento\ProductAlert\Controller\Add; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\ProductAlert\Controller\Add as AddController; use Magento\Framework\App\Action\Context; use Magento\Customer\Model\Session as CustomerSession; @@ -16,7 +17,10 @@ use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Exception\NoSuchEntityException; -class Price extends AddController +/** + * Controller for notifying about price. + */ +class Price extends AddController implements HttpPostActionInterface { /** * @var \Magento\Store\Model\StoreManagerInterface @@ -62,6 +66,8 @@ protected function isInternal($url) } /** + * Method for adding info about product alert price. + * * @return \Magento\Framework\Controller\Result\Redirect */ public function execute() @@ -75,6 +81,7 @@ public function execute() return $resultRedirect; } + $store = $this->storeManager->getStore(); try { /* @var $product \Magento\Catalog\Model\Product */ $product = $this->productRepository->getById($productId); @@ -83,11 +90,8 @@ public function execute() ->setCustomerId($this->customerSession->getCustomerId()) ->setProductId($product->getId()) ->setPrice($product->getFinalPrice()) - ->setWebsiteId( - $this->_objectManager->get(\Magento\Store\Model\StoreManagerInterface::class) - ->getStore() - ->getWebsiteId() - ); + ->setWebsiteId($store->getWebsiteId()) + ->setStoreId($store->getId()); $model->save(); $this->messageManager->addSuccess(__('You saved the alert subscription.')); } catch (NoSuchEntityException $noEntityException) { diff --git a/app/code/Magento/ProductAlert/Controller/Add/Stock.php b/app/code/Magento/ProductAlert/Controller/Add/Stock.php index 56d052f7e11e2..24cab39d544fc 100644 --- a/app/code/Magento/ProductAlert/Controller/Add/Stock.php +++ b/app/code/Magento/ProductAlert/Controller/Add/Stock.php @@ -6,6 +6,7 @@ namespace Magento\ProductAlert\Controller\Add; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\ProductAlert\Controller\Add as AddController; use Magento\Framework\App\Action\Context; use Magento\Customer\Model\Session as CustomerSession; @@ -13,29 +14,44 @@ use Magento\Framework\App\Action\Action; use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Store\Model\StoreManagerInterface; -class Stock extends AddController +/** + * Controller for notifying about stock. + */ +class Stock extends AddController implements HttpPostActionInterface { /** * @var \Magento\Catalog\Api\ProductRepositoryInterface */ protected $productRepository; + /** + * @var StoreManagerInterface + */ + private $storeManager; + /** * @param \Magento\Framework\App\Action\Context $context * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository + * @param StoreManagerInterface|null $storeManager */ public function __construct( Context $context, CustomerSession $customerSession, - ProductRepositoryInterface $productRepository + ProductRepositoryInterface $productRepository, + StoreManagerInterface $storeManager = null ) { $this->productRepository = $productRepository; parent::__construct($context, $customerSession); + $this->storeManager = $storeManager ?: $this->_objectManager + ->get(\Magento\Store\Model\StoreManagerInterface::class); } /** + * Method for adding info about product alert stock. + * * @return \Magento\Framework\Controller\Result\Redirect */ public function execute() @@ -52,15 +68,13 @@ public function execute() try { /* @var $product \Magento\Catalog\Model\Product */ $product = $this->productRepository->getById($productId); + $store = $this->storeManager->getStore(); /** @var \Magento\ProductAlert\Model\Stock $model */ $model = $this->_objectManager->create(\Magento\ProductAlert\Model\Stock::class) ->setCustomerId($this->customerSession->getCustomerId()) ->setProductId($product->getId()) - ->setWebsiteId( - $this->_objectManager->get(\Magento\Store\Model\StoreManagerInterface::class) - ->getStore() - ->getWebsiteId() - ); + ->setWebsiteId($store->getWebsiteId()) + ->setStoreId($store->getId()); $model->save(); $this->messageManager->addSuccess(__('Alert subscription has been saved.')); } catch (NoSuchEntityException $noEntityException) { diff --git a/app/code/Magento/ProductAlert/Model/Email.php b/app/code/Magento/ProductAlert/Model/Email.php index 90d9e261f97d5..18adc54c2d660 100644 --- a/app/code/Magento/ProductAlert/Model/Email.php +++ b/app/code/Magento/ProductAlert/Model/Email.php @@ -136,6 +136,11 @@ class Email extends AbstractModel */ protected $_customerHelper; + /** + * @var int + */ + private $storeId = null; + /** * @param Context $context * @param Registry $registry @@ -210,6 +215,18 @@ public function setWebsite(\Magento\Store\Model\Website $website) return $this; } + /** + * Set store id from product alert. + * + * @param int $storeId + * @return $this + */ + public function setStoreId(int $storeId) + { + $this->storeId = $storeId; + return $this; + } + /** * Set website id * @@ -330,29 +347,18 @@ protected function _getStockBlock() */ public function send() { - if ($this->_website === null || $this->_customer === null) { - return false; - } - - if (!$this->_website->getDefaultGroup() || !$this->_website->getDefaultGroup()->getDefaultStore()) { - return false; - } - - if (!in_array($this->_type, ['price', 'stock'])) { + if ($this->_website === null || $this->_customer === null || !$this->isExistDefaultStore()) { return false; } $products = $this->getProducts(); - if (count($products) === 0) { - return false; - } - $templateConfigPath = $this->getTemplateConfigPath(); - if (!$templateConfigPath) { + if (!in_array($this->_type, ['price', 'stock']) || count($products) === 0 || !$templateConfigPath) { return false; } - $store = $this->_website->getDefaultStore(); + $storeId = $this->storeId ?: (int) $this->_customer->getStoreId(); + $store = $this->getStore($storeId); $storeId = $store->getId(); $this->_appEmulation->startEnvironmentEmulation($storeId); @@ -438,4 +444,17 @@ private function getTemplateConfigPath(): string ? self::XML_PATH_EMAIL_PRICE_TEMPLATE : self::XML_PATH_EMAIL_STOCK_TEMPLATE; } + + /** + * Check if exists default store. + * + * @return bool + */ + private function isExistDefaultStore(): bool + { + if (!$this->_website->getDefaultGroup() || !$this->_website->getDefaultGroup()->getDefaultStore()) { + return false; + } + return true; + } } diff --git a/app/code/Magento/ProductAlert/Model/Observer.php b/app/code/Magento/ProductAlert/Model/Observer.php index 1870989f11dc7..addc61d2f49a9 100644 --- a/app/code/Magento/ProductAlert/Model/Observer.php +++ b/app/code/Magento/ProductAlert/Model/Observer.php @@ -218,6 +218,7 @@ protected function _processPrice(\Magento\ProductAlert\Model\Email $email) $previousCustomer = null; $email->setWebsite($website); foreach ($collection as $alert) { + $this->setAlertStoreId($alert, $email); try { if (!$previousCustomer || $previousCustomer->getId() != $alert->getCustomerId()) { $customer = $this->customerRepository->getById($alert->getCustomerId()); @@ -311,6 +312,7 @@ protected function _processStock(\Magento\ProductAlert\Model\Email $email) $previousCustomer = null; $email->setWebsite($website); foreach ($collection as $alert) { + $this->setAlertStoreId($alert, $email); try { if (!$previousCustomer || $previousCustomer->getId() != $alert->getCustomerId()) { $customer = $this->customerRepository->getById($alert->getCustomerId()); @@ -427,4 +429,21 @@ public function process() return $this; } + + /** + * Set alert store id. + * + * @param \Magento\ProductAlert\Model\Price|\Magento\ProductAlert\Model\Stock $alert + * @param Email $email + * @return Observer + */ + private function setAlertStoreId($alert, \Magento\ProductAlert\Model\Email $email) : Observer + { + $alertStoreId = $alert->getStoreId(); + if ($alertStoreId) { + $email->setStoreId((int)$alertStoreId); + } + + return $this; + } } diff --git a/app/code/Magento/ProductAlert/Model/Price.php b/app/code/Magento/ProductAlert/Model/Price.php index 0c12b7cfb489e..ecdf4578838aa 100644 --- a/app/code/Magento/ProductAlert/Model/Price.php +++ b/app/code/Magento/ProductAlert/Model/Price.php @@ -26,6 +26,8 @@ * @method \Magento\ProductAlert\Model\Price setSendCount(int $value) * @method int getStatus() * @method \Magento\ProductAlert\Model\Price setStatus(int $value) + * @method int getStoreId() + * @method \Magento\ProductAlert\Model\Stock setStoreId(int $value) * * @author Magento Core Team <core@magentocommerce.com> * @@ -60,6 +62,8 @@ public function __construct( } /** + * Create customer collection. + * * @return void */ protected function _construct() @@ -68,6 +72,8 @@ protected function _construct() } /** + * Create customer collection. + * * @return Collection */ public function getCustomerCollection() @@ -76,6 +82,8 @@ public function getCustomerCollection() } /** + * Load by param. + * * @return $this */ public function loadByParam() @@ -87,6 +95,8 @@ public function loadByParam() } /** + * Method for deleting customer from website. + * * @param int $customerId * @param int $websiteId * @return $this diff --git a/app/code/Magento/ProductAlert/Model/Stock.php b/app/code/Magento/ProductAlert/Model/Stock.php index 4d4dea5c2fe7e..99ba95e633904 100644 --- a/app/code/Magento/ProductAlert/Model/Stock.php +++ b/app/code/Magento/ProductAlert/Model/Stock.php @@ -24,6 +24,8 @@ * @method \Magento\ProductAlert\Model\Stock setSendCount(int $value) * @method int getStatus() * @method \Magento\ProductAlert\Model\Stock setStatus(int $value) + * @method int getStoreId() + * @method \Magento\ProductAlert\Model\Stock setStoreId(int $value) * * @author Magento Core Team <core@magentocommerce.com> * @@ -58,6 +60,8 @@ public function __construct( } /** + * Class constructor. + * * @return void */ protected function _construct() @@ -66,6 +70,8 @@ protected function _construct() } /** + * Create customer collection. + * * @return Collection */ public function getCustomerCollection() @@ -74,6 +80,8 @@ public function getCustomerCollection() } /** + * Load by param. + * * @return $this */ public function loadByParam() @@ -85,6 +93,8 @@ public function loadByParam() } /** + * Method for deleting customer from website. + * * @param int $customerId * @param int $websiteId * @return $this diff --git a/app/code/Magento/ProductAlert/etc/db_schema.xml b/app/code/Magento/ProductAlert/etc/db_schema.xml index ddf8be8a37e9c..1d145482ea38f 100644 --- a/app/code/Magento/ProductAlert/etc/db_schema.xml +++ b/app/code/Magento/ProductAlert/etc/db_schema.xml @@ -18,6 +18,8 @@ comment="Price amount"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website id"/> + <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="true" identity="false" + default="0" comment="Store id"/> <column xsi:type="timestamp" name="add_date" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Product alert add date"/> <column xsi:type="timestamp" name="last_send_date" on_update="false" nullable="true" @@ -38,6 +40,9 @@ <constraint xsi:type="foreign" name="PRODUCT_ALERT_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="product_alert_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> + <constraint xsi:type="foreign" name="PRODUCT_ALERT_PRICE_STORE_ID_STORE_STORE_ID" + table="product_alert_stock" column="website_id" referenceTable="store" + referenceColumn="store_id" onDelete="CASCADE"/> <index name="PRODUCT_ALERT_PRICE_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> @@ -47,6 +52,9 @@ <index name="PRODUCT_ALERT_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> + <index name="PRODUCT_ALERT_PRICE_STORE_ID" indexType="btree"> + <column name="store_id"/> + </index> </table> <table name="product_alert_stock" resource="default" engine="innodb" comment="Product Alert Stock"> <column xsi:type="int" name="alert_stock_id" padding="10" unsigned="true" nullable="false" identity="true" @@ -57,6 +65,8 @@ default="0" comment="Product id"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website id"/> + <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="true" identity="false" + default="0" comment="Store id"/> <column xsi:type="timestamp" name="add_date" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Product alert add date"/> <column xsi:type="timestamp" name="send_date" on_update="false" nullable="true" @@ -71,6 +81,9 @@ <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="product_alert_stock" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> + <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_STORE_ID_STORE_STORE_ID" + table="product_alert_stock" column="website_id" referenceTable="store" + referenceColumn="store_id" onDelete="CASCADE"/> <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="product_alert_stock" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> @@ -86,5 +99,8 @@ <index name="PRODUCT_ALERT_STOCK_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> + <index name="PRODUCT_ALERT_STOCK_STORE_ID" indexType="btree"> + <column name="store_id"/> + </index> </table> </schema> diff --git a/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json b/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json index 266d00e04c5bc..234e3d14876e5 100644 --- a/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json +++ b/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json @@ -9,19 +9,22 @@ "add_date": true, "last_send_date": true, "send_count": true, - "status": true + "status": true, + "store_id": true }, "index": { "PRODUCT_ALERT_PRICE_CUSTOMER_ID": true, "PRODUCT_ALERT_PRICE_PRODUCT_ID": true, - "PRODUCT_ALERT_PRICE_WEBSITE_ID": true + "PRODUCT_ALERT_PRICE_WEBSITE_ID": true, + "PRODUCT_ALERT_PRICE_STORE_ID": true }, "constraint": { "PRIMARY": true, "PRODUCT_ALERT_PRICE_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID": true, "PRODUCT_ALERT_PRICE_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID": true, "PRODUCT_ALERT_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID": true, - "PRODUCT_ALERT_PRICE_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true + "PRODUCT_ALERT_PRICE_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true, + "PRODUCT_ALERT_PRICE_STORE_ID_STORE_STORE_ID": true } }, "product_alert_stock": { @@ -33,19 +36,22 @@ "add_date": true, "send_date": true, "send_count": true, - "status": true + "status": true, + "store_id": true }, "index": { "PRODUCT_ALERT_STOCK_CUSTOMER_ID": true, "PRODUCT_ALERT_STOCK_PRODUCT_ID": true, - "PRODUCT_ALERT_STOCK_WEBSITE_ID": true + "PRODUCT_ALERT_STOCK_WEBSITE_ID": true, + "PRODUCT_ALERT_STOCK_STORE_ID": true }, "constraint": { "PRIMARY": true, "PRODUCT_ALERT_STOCK_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID": true, "PRODUCT_ALERT_STOCK_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID": true, "PRODUCT_ALERT_STOCK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID": true, - "PRODUCT_ALERT_STOCK_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true + "PRODUCT_ALERT_STOCK_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true, + "PRODUCT_ALERT_STOCK_STORE_ID_STORE_STORE_ID": true } } -} \ No newline at end of file +} From 2034958405344006414e44804b914dd4cbdb9e46 Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Tue, 25 Sep 2018 12:58:19 +0400 Subject: [PATCH 095/812] MAGETWO-91628: Bundle product price doubled when switching currency - Add automation test --- ...tAddProductToCartFromBundleActionGroup.xml | 24 ++++++ .../Mftf/Section/StorefrontBundledSection.xml | 5 +- ...urrencyChangingBundleProductInCartTest.xml | 77 +++++++++++++++++++ .../Mftf/Page/ConfigCurrencySetupPage.xml | 13 ++++ .../Mftf/Section/CurrencySetupSection.xml | 14 ++++ 5 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Bundle/Test/Mftf/ActionGroup/StoreFrontAddProductToCartFromBundleActionGroup.xml create mode 100644 app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/Page/ConfigCurrencySetupPage.xml create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml diff --git a/app/code/Magento/Bundle/Test/Mftf/ActionGroup/StoreFrontAddProductToCartFromBundleActionGroup.xml b/app/code/Magento/Bundle/Test/Mftf/ActionGroup/StoreFrontAddProductToCartFromBundleActionGroup.xml new file mode 100644 index 0000000000000..441303e8f1b84 --- /dev/null +++ b/app/code/Magento/Bundle/Test/Mftf/ActionGroup/StoreFrontAddProductToCartFromBundleActionGroup.xml @@ -0,0 +1,24 @@ +<?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="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StoreFrontAddProductToCartFromBundleWithCurrencyActionGroup"> + <arguments> + <argument name="product"/> + <argument name="currency" type="string" defaultValue="US Dollar"/> + </arguments> + <click selector="{{StorefrontBundledSection.currencyTrigger}}" stepKey="openCurrencyTrigger"/> + <click selector="{{StorefrontBundledSection.currency(currency)}}" stepKey="chooseCurrency"/> + <click selector="{{StorefrontBundledSection.addToCart}}" stepKey="clickCustomize"/> + <waitForPageLoad stepKey="waitForBundleOpen"/> + <checkOption selector="{{StorefrontBundledSection.productInBundle(product.name)}}" stepKey="chooseProduct"/> + <click selector="{{StorefrontBundledSection.addToCartConfigured}}" stepKey="addToCartProduct"/> + <scrollToTopOfPage stepKey="scrollToTop"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml b/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml index f724f9bbfe1bd..5646ecf812a3f 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="StorefrontBundledSection"> <element name="nthBundledOption" type="input" selector=".option:nth-of-type({{numOption}}) .choice:nth-of-type({{numOptionSelect}}) input" parameterized="true"/> <element name="addToCart" type="button" selector="#bundle-slide" timeout="30"/> @@ -24,10 +24,13 @@ <element name="bundleProductName" type="text" selector="//*[@id='maincontent']//span[@itemprop='name']"/> <element name="pageNotFound" type="text" selector="//h1[@class='page-title']//span[contains(., 'Whoops, our bad...')]"/> <element name="dropDownOptionOneProducts" type="select" selector="//label//span[contains(text(), '{{productName}}')]/../..//div[@class='control']//select" parameterized="true"/> + <element name="productInBundle" type="select" selector="//label//span[contains(text(), '{{productName}}')]" parameterized="true"/> <element name="dropDownOptionOneQuantity" type="input" selector="//span[contains(text(), '{{productName}}')]/../..//input" parameterized="true"/> <element name="radioButtonOptionTwoProducts" type="checkbox" selector="//label//span[contains(text(), '{{productName}}')]/../..//div[@class='control']//div[@class='field choice'][{{productNumber}}]/input" parameterized="true"/> <element name="radioButtonOptionTwoQuantity" type="input" selector="//label//span[contains(text(), '{{productName}}')]/../..//div[@class='control']//div[@class='field qty qty-holder']//input" parameterized="true"/> <element name="checkboxOptionThreeProducts" type="checkbox" selector="//label//span[contains(text(), '{{productName}}')]/../..//div[@class='control']//div[@class='field choice'][{{productNumber}}]/input" parameterized="true"/> <element name="multiselectOptionFourProducts" type="multiselect" selector="//label//span[contains(text(), '{{productName}}')]/../..//select[@multiple='multiple']" parameterized="true"/> + <element name="currencyTrigger" type="select" selector="#switcher-currency-trigger" timeout="30"/> + <element name="currency" type="select" selector="//a[text()='{{arg}}']" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml new file mode 100644 index 0000000000000..b7e716dc15ece --- /dev/null +++ b/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml @@ -0,0 +1,77 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CurrencyChangingBundleProductInCartTest"> + <annotations> + <features value="Bundle"/> + <stories value="Check that after changing currency price of cart is correct when the bundle product added to the cart"/> + <title value="User should be able change the currency and get right price in cart when the bundle product added to the cart"/> + <description value="User should be able change the currency and add one more product in cart and get right price in previous currency"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94467"/> + <group value="Bundle"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + </before> + <after> + <!-- Delete the bundled product --> + <actionGroup stepKey="deleteBundle" ref="deleteProductUsingProductGrid"> + <argument name="product" value="BundleProduct"/> + </actionGroup> + <actionGroup ref="AdminClearFiltersActionGroup" stepKey="ClearFiltersAfter"/> + <!--Clear Configs--> + <amOnPage url="{{AdminLoginPage.url}}" stepKey="navigateToAdmin"/> + <waitForPageLoad stepKey="waitForAdminLoginPageLoad"/> + <amOnPage url="{{ConfigCurrencySetupPage.url}}" stepKey="navigateToConfigCurrencySetupPage"/> + <waitForPageLoad stepKey="waitForConfigCurrencySetupPageForUnselectEuroCurrency"/> + <unselectOption selector="{{CurrencySetupSection.allowCurrencies}}" userInput="Euro" stepKey="unselectEuro"/> + <click stepKey="saveUnselectedConfigs" selector="{{AdminConfigSection.saveButton}}"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="logout"/> + <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> + <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> + </after> + <!--Go to bundle product creation page--> + <amOnPage url="{{AdminProductCreatePage.url(BundleProduct.set, BundleProduct.type)}}" stepKey="goToBundleProductCreationPage"/> + <waitForPageLoad stepKey="waitForBundleProductCreatePageToLoad"/> + <actionGroup ref="fillMainBundleProductForm" stepKey="fillMainFieldsForBundle"/> + <!-- Add Option, a "Radio Buttons" type option --> + <actionGroup ref="addBundleOptionWithTwoProducts" stepKey="addBundleOptionWithTwoProducts2"> + <argument name="x" value="0"/> + <argument name="n" value="1"/> + <argument name="prodOneSku" value="$$simpleProduct1.sku$$"/> + <argument name="prodTwoSku" value="$$simpleProduct2.sku$$"/> + <argument name="optionTitle" value="Option"/> + <argument name="inputType" value="radio"/> + </actionGroup> + <checkOption selector="{{AdminProductFormBundleSection.userDefinedQuantity('0', '0')}}" stepKey="userDefinedQuantitiyOptionProduct0"/> + <checkOption selector="{{AdminProductFormBundleSection.userDefinedQuantity('0', '1')}}" stepKey="userDefinedQuantitiyOptionProduct1"/> + <actionGroup ref="saveProductForm" stepKey="saveProduct"/> + <amOnPage url="{{ConfigCurrencySetupPage.url}}" stepKey="navigateToConfigCurrencySetupPage"/> + <waitForPageLoad stepKey="waitForConfigCurrencySetupPage"/> + <selectOption selector="{{CurrencySetupSection.allowCurrencies}}" parameterArray="['Euro', 'US Dollar']" stepKey="selectCurrencies"/> + <click stepKey="saveConfigs" selector="{{AdminConfigSection.saveButton}}"/> + <!-- Go to storefront BundleProduct --> + <amOnPage url="{{BundleProduct.sku}}.html" stepKey="goToStorefront"/> + <waitForPageLoad stepKey="waitForStorefront"/> + <actionGroup ref="StoreFrontAddProductToCartFromBundleWithCurrencyActionGroup" stepKey="addProduct1ToCartAndChangeCurrencyToEuro"> + <argument name="product" value="$$simpleProduct1$$"/> + <argument name="currency" value="EUR - Euro"/> + </actionGroup> + <actionGroup ref="StoreFrontAddProductToCartFromBundleWithCurrencyActionGroup" stepKey="addProduct2ToCartAndChangeCurrencyToUSD"> + <argument name="product" value="$$simpleProduct2$$"/> + <argument name="currency" value="USD - US Dollar"/> + </actionGroup> + <click stepKey="openMiniCart" selector="{{StorefrontMinicartSection.showCart}}"/> + <waitForPageLoad stepKey="waitForMiniCart"/> + <see stepKey="seeCartSubtotal" userInput="$12,300.00"/> + </test> +</tests> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Page/ConfigCurrencySetupPage.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Page/ConfigCurrencySetupPage.xml new file mode 100644 index 0000000000000..f523cb58d3bb6 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Page/ConfigCurrencySetupPage.xml @@ -0,0 +1,13 @@ +<?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="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="ConfigCurrencySetupPage" url="admin/system_config/edit/section/currency" area="admin" module="Magento_Config"> + </page> +</pages> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml new file mode 100644 index 0000000000000..16101409ad7e8 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml @@ -0,0 +1,14 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="CurrencySetupSection"> + <element name="allowCurrencies" type="select" selector="#currency_options_allow"/> + </section> +</sections> \ No newline at end of file From 25cedef8c15ead70195ec7117f4995fbcd5bddf2 Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Tue, 25 Sep 2018 13:03:19 +0400 Subject: [PATCH 096/812] MAGETWO-91628: Bundle product price doubled when switching currency - Revert xsi --- .../Bundle/Test/Mftf/Section/StorefrontBundledSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml b/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml index 5646ecf812a3f..ad74cfff54bd9 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontBundledSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="StorefrontBundledSection"> <element name="nthBundledOption" type="input" selector=".option:nth-of-type({{numOption}}) .choice:nth-of-type({{numOptionSelect}}) input" parameterized="true"/> <element name="addToCart" type="button" selector="#bundle-slide" timeout="30"/> From d447ad902a61a3ef6b4b1f2303edfee479d1112e Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Tue, 25 Sep 2018 15:29:09 +0400 Subject: [PATCH 097/812] MAGETWO-91609: Problems with operator more/less in the "catalog Products List" widget - Add automated test --- .../Section/AdminCategoryContentSection.xml | 1 + .../AdminCategoryDisplaySettingsSection.xml | 15 ++ .../AdminCreateBlockWithWidgetActionGroup.xml | 49 ++++++ .../Mftf/Section/CatalogWidgetSection.xml | 25 +++ .../CatalogProductListWidgetOperatorsTest.xml | 156 ++++++++++++++++++ 5 files changed, 246 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryDisplaySettingsSection.xml create mode 100644 app/code/Magento/CatalogWidget/Test/Mftf/ActionGroup/AdminCreateBlockWithWidgetActionGroup.xml create mode 100644 app/code/Magento/CatalogWidget/Test/Mftf/Section/CatalogWidgetSection.xml create mode 100644 app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml index 59537274f23c9..742ff4760eada 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml @@ -15,5 +15,6 @@ <element name="uploadImageFile" type="input" selector=".file-uploader-area>input"/> <element name="imageFileName" type="text" selector=".file-uploader-filename"/> <element name="removeImageButton" type="button" selector=".file-uploader-summary .action-remove"/> + <element name="AddCMSBlock" type="select" selector="//*[@name='landing_page']"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryDisplaySettingsSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryDisplaySettingsSection.xml new file mode 100644 index 0000000000000..daa00eb0a27b7 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryDisplaySettingsSection.xml @@ -0,0 +1,15 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminCategoryDisplaySettingsSection"> + <element name="settingsHeader" type="button" selector="//*[contains(text(),'Display Settings')]" timeout="30"/> + <element name="displayMode" type="button" selector="//*[@name='display_mode']"/> + </section> +</sections> diff --git a/app/code/Magento/CatalogWidget/Test/Mftf/ActionGroup/AdminCreateBlockWithWidgetActionGroup.xml b/app/code/Magento/CatalogWidget/Test/Mftf/ActionGroup/AdminCreateBlockWithWidgetActionGroup.xml new file mode 100644 index 0000000000000..1f54ff40283b1 --- /dev/null +++ b/app/code/Magento/CatalogWidget/Test/Mftf/ActionGroup/AdminCreateBlockWithWidgetActionGroup.xml @@ -0,0 +1,49 @@ +<?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="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminCreateBlockWithWidget"> + <arguments> + <argument name="addCondition" type="string"/> + <argument name="isCondition" type="string"/> + <argument name="fieldCondition" type="string"/> + </arguments> + + <click stepKey="clickShowHideButton" selector="{{BlockWYSIWYGSection.ShowHideBtn}}"/> + <waitForElementVisible stepKey="waitForInsertWidgetButton" selector="{{CatalogWidgetSection.insertWidgetButton}}"/> + + <selectOption stepKey="selectAllStoreView" userInput="All Store Views" selector="{{CatalogWidgetSection.storeViewOption}}"/> + <fillField selector="{{BlockContentSection.TextArea}}" userInput="" stepKey="makeContentFieldEmpty"/> + + <click selector="{{CatalogWidgetSection.insertWidgetButton}}" stepKey="clickInsertWidgetButton"/> + <waitForElementVisible stepKey="waitForInsertWidgetFrame" selector="{{InsertWidgetSection.widgetTypeDropDown}}" time="10"/> + + <selectOption selector="{{InsertWidgetSection.widgetTypeDropDown}}" userInput="Catalog Products List" stepKey="selectCatalogProductListOption"/> + <waitForElementVisible stepKey="waitForConditionsElementBecomeAvailable" selector="{{InsertWidgetSection.conditionsAddButton}}"/> + + <click selector="{{InsertWidgetSection.conditionsAddButton}}" stepKey="clickToAddCondition"/> + <waitForElementVisible stepKey="waitForSelectBoxOpened" selector="{{InsertWidgetSection.conditionsSelectBox}}"/> + + <selectOption selector="{{InsertWidgetSection.conditionsSelectBox}}" userInput="{{addCondition}}" stepKey="selectConditionsSelectBox"/> + <waitForElementVisible stepKey="seeConditionsAdded" selector="{{InsertWidgetSection.addCondition('1')}}"/> + + <click selector="{{InsertWidgetSection.conditionIs}}" stepKey="clickToConditionIs"/> + <selectOption selector="{{InsertWidgetSection.conditionOperator('1')}}" stepKey="selectOperatorGreaterThan" userInput="{{isCondition}}"/> + + <click selector="{{InsertWidgetSection.addCondition('1')}}" stepKey="clickAddConditionItem"/> + <waitForElementVisible stepKey="waitForConditionFieldOpened" selector="{{InsertWidgetSection.conditionField('1')}}"/> + + <fillField selector="{{InsertWidgetSection.conditionField('1')}}" stepKey="setOperator" userInput="{{fieldCondition}}"/> + <click selector="{{WidgetSection.InsertWidget}}" stepKey="clickInsertWidget"/> + + <waitForElementVisible stepKey="waitForInsertWidgetSaved" selector="{{InsertWidgetSection.save}}"/> + <click stepKey="clickSaveButton" selector="{{InsertWidgetSection.save}}"/> + <see userInput="You saved the block." stepKey="seeSavedBlockMsgOnForm"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/CatalogWidget/Test/Mftf/Section/CatalogWidgetSection.xml b/app/code/Magento/CatalogWidget/Test/Mftf/Section/CatalogWidgetSection.xml new file mode 100644 index 0000000000000..2957cfdfe6f43 --- /dev/null +++ b/app/code/Magento/CatalogWidget/Test/Mftf/Section/CatalogWidgetSection.xml @@ -0,0 +1,25 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="CatalogWidgetSection"> + <element name="insertWidgetButton" type="button" selector=".scalable.action-add-widget.plugin"/> + <element name="storeViewOption" type="button" selector="//*[@name='store_id']"/> + </section> + + <section name="InsertWidgetSection"> + <element name="widgetTypeDropDown" type="select" selector="#select_widget_type"/> + <element name="conditionsAddButton" type="button" selector=".rule-param.rule-param-new-child"/> + <element name="conditionsSelectBox" type="button" selector="#conditions__1__new_child"/> + <element name="addCondition" type="button" selector="//*[@id='conditions__1--{{arg1}}__value']/../preceding-sibling::a" parameterized="true"/> + <element name="conditionField" type="button" selector="#conditions__1--{{arg2}}__value" parameterized="true"/> + <element name="save" type="button" selector="#save-button"/> + <element name="conditionIs" type="button" selector="//*[@id='conditions__1--1__attribute']/following-sibling::span[1]"/> + <element name="conditionOperator" type="button" selector="#conditions__1--{{arg3}}__operator" parameterized="true"/> + <element name="checkElementStorefrontByPrice" type="button" selector="//*[@class='product-items widget-product-grid']//*[contains(text(),'${{arg4}}.00')]" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml b/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml new file mode 100644 index 0000000000000..53a4ccb608a6d --- /dev/null +++ b/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml @@ -0,0 +1,156 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CatalogProductListWidgetOperatorsTest"> + <annotations> + <features value="CatalogWidget"/> + <stories value="MAGETWO-91609: Problems with operator more/less in the 'catalog Products List' widget"/> + <title value="Checking operator more/less in the 'catalog Products List' widget"/> + <description value="Check 'less than', 'equals or greater than', 'equals or less than' operators"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94479"/> + <group value="CatalogWidget"/> + </annotations> + + <before> + <createData entity="SimpleSubCategory" stepKey="simplecategory"/> + <createData entity="SimpleProduct" stepKey="createFirstProduct"> + <requiredEntity createDataKey="simplecategory"/> + <field key="price">10</field> + </createData> + <createData entity="SimpleProduct" stepKey="createSecondProduct"> + <requiredEntity createDataKey="simplecategory"/> + <field key="price">50</field> + </createData> + <createData entity="SimpleProduct" stepKey="createThirdProduct"> + <requiredEntity createDataKey="simplecategory"/> + <field key="price">100</field> + </createData> + + <createData entity="_defaultBlock" stepKey="createPreReqBlock"/> + <!--User log in on back-end as admin--> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> + </before> + + <!--Open block with widget.--> + <actionGroup ref="navigateToCreatedCMSBlockPage" stepKey="navigateToCreatedCMSBlockPage1"> + <argument name="CMSBlockPage" value="$$createPreReqBlock$$"/> + </actionGroup> + + <actionGroup ref="AdminCreateBlockWithWidget" stepKey="adminCreateBlockWithWidget"> + <argument name="addCondition" value="Price"/> + <argument name="isCondition" value="greater than"/> + <argument name="fieldCondition" value="20"/> + </actionGroup> + + <!--Go to Catalog > Categories (choose category where created products)--> + <amOnPage url="{{AdminCategoryPage.url}}" stepKey="onCategoryIndexPage"/> + <waitForPageLoad stepKey="waitForCategoryPageLoadAddProducts" after="onCategoryIndexPage"/> + <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickExpandAll" after="waitForCategoryPageLoadAddProducts"/> + <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleSubCategory.name)}}" stepKey="clickCategoryLink"/> + <waitForPageLoad stepKey="waitForCategoryPageLoad"/> + + <!--Content > Add CMS Block: name saved block--> + <waitForElementVisible selector="{{AdminCategoryContentSection.sectionHeader}}" stepKey="waitForContentSection"/> + <conditionalClick selector="{{AdminCategoryContentSection.sectionHeader}}" dependentSelector="{{AdminCategoryContentSection.uploadButton}}" visible="false" stepKey="openContentSection"/> + <waitForPageLoad stepKey="waitForContentLoad"/> + + <selectOption selector="{{AdminCategoryContentSection.AddCMSBlock}}" stepKey="selectSavedBlock" userInput="{{_defaultBlock.title}}"/> + + <!--Display Settings > Display Mode: Static block only--> + <waitForElementVisible selector="{{AdminCategoryDisplaySettingsSection.settingsHeader}}" stepKey="waitForDisplaySettingsSection"/> + <conditionalClick selector="{{AdminCategoryDisplaySettingsSection.settingsHeader}}" dependentSelector="{{AdminCategoryDisplaySettingsSection.displayMode}}" visible="false" stepKey="openDisplaySettingsSection"/> + <waitForPageLoad stepKey="waitForDisplaySettingsLoad"/> + <selectOption stepKey="selectStaticBlockOnlyOption" userInput="Static block only" selector="{{AdminCategoryDisplaySettingsSection.displayMode}}"/> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategoryWithProducts"/> + <waitForPageLoad stepKey="waitForCategorySaved"/> + <see userInput="You saved the category." stepKey="seeSuccessMessage"/> + + <!--Go to Storefront > category--> + <amOnPage url="$$simplecategory.name$$.html" stepKey="goToStorefrontCategoryPage"/> + <waitForPageLoad stepKey="waitForStorefrontPageLoaded"/> + + <!--Check operators Greater than--> + <dontSeeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('10')}}" stepKey="dontSeeElementByPrice20"/> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('50')}}" stepKey="seeElementByPrice50"/> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('100')}}" stepKey="seeElementByPrice100"/> + + <!--Open block with widget.--> + <actionGroup ref="navigateToCreatedCMSBlockPage" stepKey="navigateToCreatedCMSBlockPage2"> + <argument name="CMSBlockPage" value="$$createPreReqBlock$$"/> + </actionGroup> + + <actionGroup ref="AdminCreateBlockWithWidget" stepKey="adminCreateBlockWithWidgetLessThan"> + <argument name="addCondition" value="Price"/> + <argument name="isCondition" value="less than"/> + <argument name="fieldCondition" value="20"/> + </actionGroup> + + <!--Go to Storefront > category--> + <amOnPage url="$$simplecategory.name$$.html" stepKey="goToStorefrontCategoryPage2"/> + <waitForPageLoad stepKey="waitForStorefrontPageLoaded2"/> + + <!--Check operators Greater than--> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('10')}}" stepKey="seeElementByPrice20"/> + <dontSeeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('50')}}" stepKey="dontSeeElementByPrice50"/> + <dontSeeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('100')}}" stepKey="dontSeeElementByPrice100"/> + + <!--Open block with widget.--> + <actionGroup ref="navigateToCreatedCMSBlockPage" stepKey="navigateToCreatedCMSBlockPage3"> + <argument name="CMSBlockPage" value="$$createPreReqBlock$$"/> + </actionGroup> + + <actionGroup ref="AdminCreateBlockWithWidget" stepKey="adminCreateBlockWithWidgetEqualsOrGreaterThan"> + <argument name="addCondition" value="Price"/> + <argument name="isCondition" value="equals or greater than"/> + <argument name="fieldCondition" value="50"/> + </actionGroup> + + <!--Go to Storefront > category--> + <amOnPage url="$$simplecategory.name$$.html" stepKey="goToStorefrontCategoryPage3"/> + <waitForPageLoad stepKey="waitForStorefrontPageLoaded3"/> + + <!--Check operators Greater than--> + <dontSeeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('10')}}" stepKey="dontSeeElementByPrice20s"/> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('50')}}" stepKey="seeElementByPrice50s"/> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('100')}}" stepKey="seeElementByPrice100s"/> + + <!--Open block with widget.--> + <actionGroup ref="navigateToCreatedCMSBlockPage" stepKey="navigateToCreatedCMSBlockPage4"> + <argument name="CMSBlockPage" value="$$createPreReqBlock$$"/> + </actionGroup> + + <actionGroup ref="AdminCreateBlockWithWidget" stepKey="adminCreateBlockWithWidgetEqualsOrLessThan"> + <argument name="addCondition" value="Price"/> + <argument name="isCondition" value="equals or less than"/> + <argument name="fieldCondition" value="50"/> + </actionGroup> + + <!--Go to Storefront > category--> + <amOnPage url="$$simplecategory.name$$.html" stepKey="goToStorefrontCategoryPage4"/> + <waitForPageLoad stepKey="waitForStorefrontPageLoaded4"/> + + <!--Check operators Greater than--> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('10')}}" stepKey="seeElementByPrice20s"/> + <seeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('50')}}" stepKey="seeElementByPrice50t"/> + <dontSeeElement selector="{{InsertWidgetSection.checkElementStorefrontByPrice('100')}}" stepKey="dontSeeElementByPrice100s"/> + + <after> + <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> + <deleteData createDataKey="createPreReqBlock" stepKey="deletePreReqBlock" /> + <deleteData createDataKey="simplecategory" stepKey="deleteSimpleCategory"/> + <deleteData createDataKey="createFirstProduct" stepKey="deleteFirstProduct"/> + <deleteData createDataKey="createSecondProduct" stepKey="deleteSecondProduct"/> + <deleteData createDataKey="createThirdProduct" stepKey="deleteThirdProduct"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + </test> +</tests> From 99b518a6ce248fc61db7a194a05d477422d71b2e Mon Sep 17 00:00:00 2001 From: Aleksey Tsoy <aleksey_tsoy@epam.com> Date: Tue, 25 Sep 2018 18:10:16 +0600 Subject: [PATCH 098/812] MAGETWO-91658: Wrong Checkout Totals Sort Order in cart - Added automated test --- .../Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml index e1ec9032e072a..08623da68a8ef 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml @@ -5,8 +5,7 @@ * See COPYING.txt for license details. */ --> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="CheckoutTotalsSortOrderInCartTest"> <annotations> <title value="Checkout Totals Sort Order configuration and displaying in cart"/> From 1b8cd089461f20131a8b5e5784238918138e13ae Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <mikalai_shostka@epam.com> Date: Tue, 25 Sep 2018 15:25:55 +0300 Subject: [PATCH 099/812] MAGETWO-70303: [GITHUB] Anchor categories are showing products of disabled subcategories #9002 - Change index table and temporary table --- .../Category/Product/AbstractAction.php | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php index d312b78e74059..a1358c02ce9fc 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php @@ -123,6 +123,11 @@ abstract class AbstractAction */ private $queryGenerator; + /** + * @var int + */ + private $currentStoreId = 0; + /** * @param ResourceConnection $resource * @param \Magento\Store\Model\StoreManagerInterface $storeManager @@ -164,6 +169,7 @@ protected function reindex() { foreach ($this->storeManager->getStores() as $store) { if ($this->getPathFromCategoryId($store->getRootCategoryId())) { + $this->currentStoreId = $store->getId(); $this->reindexRootCategory($store); $this->reindexAnchorCategories($store); $this->reindexNonAnchorCategories($store); @@ -499,7 +505,7 @@ protected function createAnchorSelect(Store $store) 'cc2.parent_id = cc.entity_id AND cc.entity_id NOT IN (' . implode( ',', $rootCatIds - ) . ') AND cc2.store_id = ' . $store->getId(), + ) . ')', [] )->joinInner( ['ccp' => $this->getTable('catalog_category_product')], @@ -631,12 +637,6 @@ protected function makeTempCategoryTreeIndex() null, ['nullable' => false, 'unsigned' => true] ); - $temporaryTable->addColumn( - 'store_id', - \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, - null, - ['nullable' => false, 'unsigned' => true] - ); // Each entry will be unique. $temporaryTable->addIndex( 'idx_primary', @@ -649,12 +649,6 @@ protected function makeTempCategoryTreeIndex() ['child_id'], ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX] ); - - $temporaryTable->addIndex( - 'store_id', - ['store_id'], - ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX] - ); // Drop the temporary table in case it already exists on this (persistent?) connection. $this->connection->dropTemporaryTable($temporaryName); $this->connection->createTemporaryTable($temporaryTable); @@ -684,11 +678,19 @@ protected function fillTempCategoryTreeIndex($temporaryName) ['c' => $this->getTable('catalog_category_entity')], ['entity_id', 'path'] )->joinInner( - ['ccei' => $this->getTable('catalog_category_entity_int')], - 'ccei.' . $categoryLinkField . ' = c.' . $categoryLinkField . - ' AND ccei.attribute_id = ' . $isActiveAttributeId . - ' AND ccei.value = 1', - ['store_id'] + ['ccacd' => $this->getTable('catalog_category_entity_int')], + 'ccacd.' . $categoryLinkField . ' = c.' . $categoryLinkField . ' AND ccacd.store_id = 0' . + ' AND ccacd.attribute_id = ' . $isActiveAttributeId, + [] + )->joinLeft( + ['ccacs' => $this->getTable('catalog_category_entity_int')], + 'ccacs.' . $categoryLinkField . ' = c.' . $categoryLinkField + . ' AND ccacs.attribute_id = ccacd.attribute_id AND ccacs.store_id = ' . + $this->currentStoreId, + [] + )->where( + $this->connection->getIfNullSql('ccacs.value', 'ccacd.value') . ' = ?', + 1 ), 'entity_id' ); @@ -699,13 +701,13 @@ protected function fillTempCategoryTreeIndex($temporaryName) foreach ($this->connection->fetchAll($select) as $category) { foreach (explode('/', $category['path']) as $parentId) { if ($parentId !== $category['entity_id']) { - $values[] = [$parentId, $category['entity_id'], $category['store_id']]; + $values[] = [$parentId, $category['entity_id']]; } } } if (count($values) > 0) { - $this->connection->insertArray($temporaryName, ['parent_id', 'child_id', 'store_id'], $values); + $this->connection->insertArray($temporaryName, ['parent_id', 'child_id'], $values); } } } From 12634b0bc936f92ab8b37dbfec5f781e790551d7 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Tue, 25 Sep 2018 15:57:04 +0300 Subject: [PATCH 100/812] MAGETWO-95137: [2.3] Return path e-mail variable system/smtp/return_path_email doesn't work --- app/code/Magento/Email/Model/Transport.php | 44 ++++++++++++++-------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Email/Model/Transport.php b/app/code/Magento/Email/Model/Transport.php index 5a4d64e6d6c0e..c270c3086cca9 100644 --- a/app/code/Magento/Email/Model/Transport.php +++ b/app/code/Magento/Email/Model/Transport.php @@ -31,6 +31,23 @@ class Transport implements TransportInterface */ const XML_PATH_SENDING_RETURN_PATH_EMAIL = 'system/smtp/return_path_email'; + /** + * Configuration of whether return path should be set or no. + * + * Possible values are: + * 0 - no + * 1 - yes (set value as FROM address) + * 2 - use custom value + * + * @var int + */ + private $isSetReturnPath; + + /** + * @var string|null + */ + private $returnPathValue; + /** * @var Sendmail */ @@ -51,25 +68,15 @@ public function __construct( ScopeConfigInterface $scopeConfig, $parameters = null ) { - /* configuration of whether return path should be set or no. Possible values are: - * 0 - no - * 1 - yes (set value as FROM address) - * 2 - use custom value - * @see Magento\Config\Model\Config\Source\Yesnocustom - */ - $isSetReturnPath = $scopeConfig->getValue( + $this->isSetReturnPath = (int) $scopeConfig->getValue( self::XML_PATH_SENDING_SET_RETURN_PATH, ScopeInterface::SCOPE_STORE ); - $returnPathValue = $scopeConfig->getValue( + $this->returnPathValue = $scopeConfig->getValue( self::XML_PATH_SENDING_RETURN_PATH_EMAIL, ScopeInterface::SCOPE_STORE ); - if ($isSetReturnPath == '2' && $returnPathValue !== null) { - $parameters .= ' -f' . \escapeshellarg($returnPathValue); - } - $this->zendTransport = new Sendmail($parameters); $this->message = $message; } @@ -80,9 +87,16 @@ public function __construct( public function sendMessage() { try { - $this->zendTransport->send( - Message::fromString($this->message->getRawMessage()) - ); + $zendMessage = Message::fromString($this->message->getRawMessage()); + if (2 === $this->isSetReturnPath && $this->returnPathValue) { + $zendMessage->setSender($this->returnPathValue); + } elseif (1 === $this->isSetReturnPath && $zendMessage->getFrom()->count()) { + $fromAddressList = $zendMessage->getFrom(); + $fromAddressList->rewind(); + $zendMessage->setSender($fromAddressList->current()->getEmail()); + } + + $this->zendTransport->send($zendMessage); } catch (\Exception $e) { throw new MailException(new Phrase($e->getMessage()), $e); } From ca3f8ba315ec2c810ee077ba1bacf7bcf371026a Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Tue, 25 Sep 2018 17:07:29 +0300 Subject: [PATCH 101/812] MAGETWO-91628: Bundle product price doubled when switching currency - Fixed unit tests; --- .../Bundle/Test/Unit/Model/Product/TypeTest.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php index 4bbf5641c55d3..9819abf62a273 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php @@ -513,10 +513,6 @@ function ($key) use ($optionCollection, $selectionCollection) { ->method('getSelectionId') ->willReturn(314); - $this->priceCurrency->expects($this->once()) - ->method('convert') - ->willReturn(3.14); - $result = $this->model->prepareForCartAdvanced($buyRequest, $product); $this->assertEquals([$product, $productType], $result); } @@ -737,10 +733,6 @@ function ($key) use ($optionCollection, $selectionCollection) { ->method('prepareForCart') ->willReturn([]); - $this->priceCurrency->expects($this->once()) - ->method('convert') - ->willReturn(3.14); - $result = $this->model->prepareForCartAdvanced($buyRequest, $product); $this->assertEquals('We can\'t add this item to your shopping cart right now.', $result); } @@ -961,10 +953,6 @@ function ($key) use ($optionCollection, $selectionCollection) { ->method('prepareForCart') ->willReturn('string'); - $this->priceCurrency->expects($this->once()) - ->method('convert') - ->willReturn(3.14); - $result = $this->model->prepareForCartAdvanced($buyRequest, $product); $this->assertEquals('string', $result); } From 0b0b141e1bc28f1264b9d1bc9d8244b66d113e77 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 25 Sep 2018 09:49:48 -0500 Subject: [PATCH 102/812] MAGETWO-94962: Unable to set default option for swatch attribute - using json serializer to serialize options to not change behavior --- .../Catalog/view/adminhtml/web/js/options.js | 16 ++++------------ .../view/adminhtml/web/js/product-attributes.js | 5 +++-- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index 7c35993670444..563d410a11383 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -187,19 +187,11 @@ define([ if (optionPanel.hasClass(activePanelClass)) { optionContainer.find('input') - .each(function () { - if (this.disabled) { - return; - } - - if (this.type === 'checkbox' || this.type === 'radio') { - if (this.checked) { - optionsValues.push(this.name + '=' + jQuery(this).val()); - } - } else { - optionsValues.push(this.name + '=' + jQuery(this).val()); - } + .serializeArray() + .map(function (el) { + swatchValues.push(el.name + '=' + el.value); }); + jQuery('<input>') .attr({ type: 'hidden', diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index d0eacc94e2c32..af31e48180793 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -447,8 +447,9 @@ define([ if (activePanel.hasClass(activePanelClass)) { optionContainer .find('input') - .each(function () { - swatchValues.push(this.name + '=' + $(this).val()); + .serializeArray() + .map(function (el) { + swatchValues.push(el.name + '=' + el.value); }); $('<input>') From b7264dfc698df3536f82c5403fea685169b71226 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <mikalai_shostka@epam.com> Date: Tue, 25 Sep 2018 18:18:27 +0300 Subject: [PATCH 103/812] MAGETWO-91596: Making order in admin with grouped product by adding it by sku with empty qty field leads to unability to order - Add automated test --- .../AdminOrderFormItemsOrderedSection.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormItemsOrderedSection.xml diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormItemsOrderedSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormItemsOrderedSection.xml new file mode 100644 index 0000000000000..11673f1f0fe26 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormItemsOrderedSection.xml @@ -0,0 +1,19 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminOrderFormItemsOrderedSection"> + <element name="addProductsBySku" type="button" selector="//section[@id='order-items']//span[contains(text(),'Add Products By SKU')]"/> + <element name="configureButtonBySku" type="button" selector="//div[@class='sku-configure-button']//span[contains(text(),'Configure')]"/> + <element name="configureProductOk" type="button" selector="//div[@class='page-main-actions']//span[contains(text(),'OK')]"/> + <element name="configureProductQtyField" type="input" selector="//*[@id='super-product-table']/tbody/tr[{{arg}}]/td[5]/input[1]" parameterized="true"/> + <element name="addProductToOrder" type="input" selector="//*[@title='Add Products to Order']"/> + <element name="itemsOrderedSummaryText" type="textarea" selector="//table[@class='data-table admin__table-primary order-tables']/tfoot/tr"/> + </section> +</sections> \ No newline at end of file From f90a8bd78ab269fcf7d3e1125a4778daeb37086b Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 25 Sep 2018 10:35:13 -0500 Subject: [PATCH 104/812] MAGETWO-94962: Unable to set default option for swatch attribute - using improved selector for form elements --- app/code/Magento/Catalog/view/adminhtml/web/js/options.js | 2 +- .../Swatches/view/adminhtml/web/js/product-attributes.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index 563d410a11383..b140ea3ea32e3 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -186,7 +186,7 @@ define([ optionContainer = optionPanel.find('table tbody'); if (optionPanel.hasClass(activePanelClass)) { - optionContainer.find('input') + optionContainer.find('input,select,textarea') .serializeArray() .map(function (el) { swatchValues.push(el.name + '=' + el.value); diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index af31e48180793..daa73ea7bce79 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -446,7 +446,7 @@ define([ if (activePanel.hasClass(activePanelClass)) { optionContainer - .find('input') + .find('input,select,textarea') .serializeArray() .map(function (el) { swatchValues.push(el.name + '=' + el.value); From 187c51a134a736883e78505bb0923259f3ed3daa Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 25 Sep 2018 12:40:46 -0500 Subject: [PATCH 105/812] MAGETWO-94962: Unable to set default option for swatch attribute - fix copy paste variable usage --- app/code/Magento/Catalog/view/adminhtml/web/js/options.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index b140ea3ea32e3..dd49be74e6808 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -189,7 +189,7 @@ define([ optionContainer.find('input,select,textarea') .serializeArray() .map(function (el) { - swatchValues.push(el.name + '=' + el.value); + optionsValues.push(el.name + '=' + el.value); }); jQuery('<input>') From caab8f7e1a1c213a7a0928b9c88f9760903ae17a Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Wed, 26 Sep 2018 13:12:32 +0300 Subject: [PATCH 106/812] MAGETWO-95137: [2.3] Return path e-mail variable system/smtp/return_path_email doesn't work --- app/code/Magento/Email/Model/Transport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Email/Model/Transport.php b/app/code/Magento/Email/Model/Transport.php index c270c3086cca9..28d2d171eecf4 100644 --- a/app/code/Magento/Email/Model/Transport.php +++ b/app/code/Magento/Email/Model/Transport.php @@ -32,7 +32,7 @@ class Transport implements TransportInterface const XML_PATH_SENDING_RETURN_PATH_EMAIL = 'system/smtp/return_path_email'; /** - * Configuration of whether return path should be set or no. + * Whether return path should be set or no. * * Possible values are: * 0 - no From 77d2386c243125a31788a11e15771ee25e786993 Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Wed, 26 Sep 2018 16:18:19 +0400 Subject: [PATCH 107/812] MAGETWO-91602: Visual Merchandiser incorrectly displays/sorts configurable product price in Tile view - Add automated test --- .../Section/AdminCreateProductConfigurationsPanelSection.xml | 1 + .../Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml index 99e47baac37d5..7901b6f2290c9 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml @@ -35,5 +35,6 @@ <element name="applySingleQuantityToEachSkus" type="radio" selector=".admin__field-label[for='apply-single-inventory-radio']" timeout="30"/> <element name="quantity" type="input" selector="#apply-single-inventory-input"/> <element name="gridLoadingMask" type="text" selector="[data-role='spinner'][data-component*='product_attributes_listing']"/> + <element name="attributeColorCheckbox" type="select" selector="//div[contains(text(),'color') and @class='data-grid-cell-content']/../preceding-sibling::td/label/input"/> </section> </sections> diff --git a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml index 25e03676f6870..b7ed7c05e071e 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml @@ -21,5 +21,6 @@ <element name="nthChooseColor" type="button" selector="#swatch-visual-options-panel table tbody tr:nth-of-type({{var}}) .swatch_row_name.colorpicker_handler" parameterized="true"/> <element name="nthUploadFile" type="button" selector="#swatch-visual-options-panel table tbody tr:nth-of-type({{var}}) .swatch_row_name.btn_choose_file_upload" parameterized="true"/> <element name="nthDelete" type="button" selector="#swatch-visual-options-panel table tbody tr:nth-of-type({{var}}) button.delete-option" parameterized="true"/> + <element name="deleteBtn" type="button" selector="#manage-options-panel:nth-of-type({{var}}) button.delete-option" parameterized="true"/> </section> </sections> From 3073ed5e8670ab9b095cc6fb6d29d875d4235ce2 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Wed, 26 Sep 2018 14:31:18 +0200 Subject: [PATCH 108/812] Shipping method set concept --- .../SetShippingMethodsOnCart.php | 105 ++++++++++++++++++ .../Magento/QuoteGraphQl/etc/schema.graphqls | 9 +- 2 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php new file mode 100644 index 0000000000000..448bdcbb37a6d --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php @@ -0,0 +1,105 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver\ShippingMethod; + +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\Stdlib\ArrayManager; +use Magento\Quote\Api\CartRepositoryInterface; +use Magento\Quote\Api\Data\CartInterface; +use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; + +class SetShippingMethodsOnCart implements ResolverInterface +{ + /** + * @var CartRepositoryInterface + */ + private $cartRepository; + + /** + * @var MaskedQuoteIdToQuoteIdInterface + */ + private $maskedQuoteIdToQuoteId; + + /** + * @var ArrayManager + */ + private $arrayManager; + + /** + * SetShippingMethodsOnCart constructor. + * @param ArrayManager $arrayManager + * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + */ + public function __construct( + ArrayManager $arrayManager, + MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, + CartRepositoryInterface $cartRepository + ) { + $this->arrayManager = $arrayManager; + $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; + $this->cartRepository = $cartRepository; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + $shippingMethods = $this->arrayManager->get('input/shipping_methods', $args); + $maskedCartId = $this->arrayManager->get('input/cart_id', $args); + + if (!$maskedCartId) { + // TODO: throw an exception + } + + if (!$shippingMethods) { + // TODO: throw an exception? + } + + foreach ($shippingMethods as $shippingMethod) { + if (empty($shippingMethod['cart_address_id'])) { + // TODO: throw input exception + } + + if (empty($shippingMethod['shipping_method_code'])) { + // TODO: throw input exception + } + + // TODO: move to a separate class + // TODO: check current customer can apply operations on specified cart + } + + $quoteId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); + $quote = $this->cartRepository->get($quoteId); // TODO: catch no such entity exception + $this->setShippingMethods($shippingMethods, $quote); + + $quote->collectTotals(); + $quote->save(); + //$this->cartRepository->save($quote); + + return 'Success!'; + } + + private function setShippingMethods($shippingMethods, CartInterface $quote) + { + $addresses = $quote->getAllShippingAddresses(); + /** @var \Magento\Quote\Model\Quote\Address $address */ + foreach ($addresses as $address) { + $addressId = $address->getId(); + $shippingMethodForAddress = array_search($addressId, array_column($shippingMethods, 'cart_address_id')); + if ($shippingMethodForAddress !== false) { + $address->setShippingMethod($shippingMethods[$shippingMethodForAddress]['shipping_method_code']); +// $address->setCollectShippingRates(1); + $address->save(); + } + } + // TODO: make sure that shipping method is assigned for all addresses + } +} \ No newline at end of file diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index b10575171781e..027e59c327ebd 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -11,7 +11,7 @@ type Mutation { removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput - setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput + setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ShippingMethod\\SetShippingMethodsOnCart") } input SetShippingAddressesOnCartInput { @@ -47,11 +47,12 @@ input CartAddressInput { } input SetShippingMethodsOnCartInput { + cart_id: String! shipping_methods: [ShippingMethodForAddressInput!]! } input ShippingMethodForAddressInput { - cart_address_id: String! + cart_address_id: String! # todo: int? shipping_method_code: String! } @@ -64,12 +65,12 @@ type SetShippingAddressesOnCartOutput { } type SetShippingMethodsOnCartOutput { - cart: Cart! + cart: String } # If no address is provided, the system get address assigned to a quote # If there's no address at all - the system returns all shipping methods -type AvailableShippingMethodsOnCartInput { +input AvailableShippingMethodsOnCartInput { cart_id: String! customer_address_id: Int address: CartAddressInput From 9a1775623fd7cfb3d5e9204033bdb70e1f2483aa Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Wed, 26 Sep 2018 16:02:54 +0300 Subject: [PATCH 109/812] MAGETWO-94991: [2.3] Magnifier does not work with Windows Chrome/FF --- lib/web/magnifier/magnify.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/web/magnifier/magnify.js b/lib/web/magnifier/magnify.js index 1fb73ea28bff1..9d673092b806c 100644 --- a/lib/web/magnifier/magnify.js +++ b/lib/web/magnifier/magnify.js @@ -35,13 +35,6 @@ define([ allowZoomOut = false, allowZoomIn = true; - if (isTouchEnabled) { - $(element).on('fotorama:showend fotorama:load', function () { - $(magnifierSelector).remove(); - $(magnifierZoomSelector).remove(); - }); - } - (function () { var style = document.documentElement.style, transitionEnabled = style.transition !== undefined || From 75ccb2485aa5543f02e8ea2aac8e7f3c93d8c2c8 Mon Sep 17 00:00:00 2001 From: vtymchynskyi <vtymchynskyi@magento.com> Date: Wed, 26 Sep 2018 15:07:58 +0300 Subject: [PATCH 110/812] MAGETWO-93394: Table rate shipment is taken from wrong website ID when creating an order through the admin --- .../Magento/Sales/Model/AdminOrder/Create.php | 17 ++- .../_files/tablerates_second_website.php | 40 +++++ .../tablerates_second_website_rollback.php | 13 ++ .../Controller/Adminhtml/Order/CreateTest.php | 137 +++++++++++++++++- .../_files/websites_different_countries.php | 14 +- 5 files changed, 215 insertions(+), 6 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website.php create mode 100644 dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website_rollback.php diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php index b690395ebab7c..088ad5a61f6c3 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Create.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php @@ -14,6 +14,7 @@ use Magento\Quote\Model\Quote\Item; use Magento\Sales\Api\Data\OrderAddressInterface; use Magento\Sales\Model\Order; +use Magento\Store\Model\StoreManagerInterface; use Psr\Log\LoggerInterface; /** @@ -242,6 +243,11 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ */ private $dataObjectConverter; + /** + * @var StoreManagerInterface + */ + private $storeManager; + /** * @param \Magento\Framework\ObjectManagerInterface $objectManager * @param \Magento\Framework\Event\ManagerInterface $eventManager @@ -273,6 +279,7 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ * @param array $data * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer * @param ExtensibleDataObjectConverter|null $dataObjectConverter + * @param StoreManagerInterface $storeManager * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -305,7 +312,8 @@ public function __construct( \Magento\Quote\Model\QuoteFactory $quoteFactory, array $data = [], \Magento\Framework\Serialize\Serializer\Json $serializer = null, - ExtensibleDataObjectConverter $dataObjectConverter = null + ExtensibleDataObjectConverter $dataObjectConverter = null, + StoreManagerInterface $storeManager = null ) { $this->_objectManager = $objectManager; $this->_eventManager = $eventManager; @@ -339,6 +347,7 @@ public function __construct( parent::__construct($data); $this->dataObjectConverter = $dataObjectConverter ?: ObjectManager::getInstance() ->get(ExtensibleDataObjectConverter::class); + $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class); } /** @@ -416,7 +425,8 @@ public function setRecollect($flag) /** * Recollect totals for customer cart. - * Set recollect totals flag for quote + * + * Set recollect totals flag for quote. * * @return $this */ @@ -1333,6 +1343,7 @@ protected function _createCustomerForm(\Magento\Customer\Api\Data\CustomerInterf /** * Set and validate Quote address + * * All errors added to _errors * * @param \Magento\Quote\Model\Quote\Address $address @@ -1536,6 +1547,8 @@ public function resetShippingMethod() */ public function collectShippingRates() { + $store = $this->getQuote()->getStore(); + $this->storeManager->setCurrentStore($store); $this->getQuote()->getShippingAddress()->setCollectShippingRates(true); $this->collectRates(); diff --git a/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website.php b/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website.php new file mode 100644 index 0000000000000..52551e6dc96d8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website.php @@ -0,0 +1,40 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\App\ResourceConnection; +use Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate; +use Magento\Store\Api\WebsiteRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var WebsiteRepositoryInterface $websiteRepository */ +$websiteRepository = $objectManager->get(WebsiteRepositoryInterface::class); +$website = $websiteRepository->get('test'); + +/** @var ResourceConnection $resource */ +$resource = $objectManager->get(ResourceConnection::class); +$connection = $resource->getConnection(); +$resourceModel = $objectManager->create(Tablerate::class); +$entityTable = $resourceModel->getTable('shipping_tablerate'); +$data = + [ + 'website_id' => $website->getId(), + 'dest_country_id' => 'US', + 'dest_region_id' => 0, + 'dest_zip' => '*', + 'condition_name' => 'package_qty', + 'condition_value' => 1, + 'price' => 20, + 'cost' => 20 + ]; +$connection->query( + "INSERT INTO {$entityTable} (`website_id`, `dest_country_id`, `dest_region_id`, `dest_zip`, `condition_name`," + . "`condition_value`, `price`, `cost`) VALUES (:website_id, :dest_country_id, :dest_region_id, :dest_zip," + . " :condition_name, :condition_value, :price, :cost);", + $data +); diff --git a/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website_rollback.php b/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website_rollback.php new file mode 100644 index 0000000000000..9606b0eb605fd --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_second_website_rollback.php @@ -0,0 +1,13 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$resource = $objectManager->get(\Magento\Framework\App\ResourceConnection::class); +$connection = $resource->getConnection(); +$resourceModel = $objectManager->create(\Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate::class); +$entityTable = $resourceModel->getTable('shipping_tablerate'); +$connection->query("DELETE FROM {$entityTable};"); diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php index efb1b12fc60ed..a07616474a410 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php @@ -6,15 +6,26 @@ namespace Magento\Sales\Controller\Adminhtml\Order; use Magento\Customer\Api\CustomerRepositoryInterface; -use Magento\Backend\Model\Session\Quote; +use Magento\Backend\Model\Session\Quote as SessionQuote; +use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\App\Config\MutableScopeConfigInterface; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Quote\Api\CartRepositoryInterface; use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Quote\Model\Quote; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Api\Data\WebsiteInterface; +use Magento\Store\Api\StoreRepositoryInterface; +use Magento\Store\Api\WebsiteRepositoryInterface; +use Magento\Store\Model\ScopeInterface; /** * @magentoAppArea adminhtml * @magentoDbIsolation enabled * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyPublicMethods) */ class CreateTest extends \Magento\TestFramework\TestCase\AbstractBackendController { @@ -70,6 +81,57 @@ public function testLoadBlockActionData() } /** + * Tests that shipping method 'Table rates' shows rates according to selected website. + * + * @magentoAppArea adminhtml + * @magentoDataFixture Magento/Quote/Fixtures/quote_sec_website.php + * @magentoDataFixture Magento/OfflineShipping/_files/tablerates_second_website.php + * @magentoDbIsolation disabled + */ + public function testLoadBlockShippingMethod() + { + $store = $this->getStore('fixture_second_store'); + + /** @var MutableScopeConfigInterface $mutableScopeConfig */ + $mutableScopeConfig = $this->_objectManager->get(MutableScopeConfigInterface::class); + $mutableScopeConfig->setValue( + 'carriers/tablerate/active', + 1, + ScopeInterface::SCOPE_STORE, + $store->getCode() + ); + $mutableScopeConfig->setValue( + 'carriers/tablerate/condition_name', + 'package_qty', + ScopeInterface::SCOPE_STORE, + $store->getCode() + ); + + $website = $this->getWebsite('test'); + $customer = $this->getCustomer('customer.web@example.com', (int)$website->getId()); + $quote = $this->getQuoteById('0000032134'); + $session = $this->_objectManager->get(SessionQuote::class); + $session->setQuoteId($quote->getId()); + + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue( + [ + 'customer_id' => $customer->getId(), + 'collect_shipping_rates' => 1, + 'store_id' => $store->getId(), + 'json' => true + ] + ); + $this->dispatch('backend/sales/order_create/loadBlock/block/shipping_method'); + $body = $this->getResponse()->getBody(); + $expectedTableRatePrice = '<span class=\"price\">$20.00<\/span>'; + + $this->assertContains($expectedTableRatePrice, $body, ''); + } + + /** + * Tests LoadBlock actions. + * * @param string $block Block name. * @param string $expected Contains HTML. * @@ -100,6 +162,8 @@ public function loadBlockActionsDataProvider() } /** + * Tests action items. + * * @magentoDataFixture Magento/Catalog/_files/product_simple.php */ public function testLoadBlockActionItems() @@ -174,6 +238,8 @@ public function testIndexAction() } /** + * Tests ACL. + * * @param string $actionName * @param boolean $reordered * @param string $expectedResult @@ -183,7 +249,7 @@ public function testIndexAction() */ public function testGetAclResource($actionName, $reordered, $expectedResult) { - $this->_objectManager->get(Quote::class)->setReordered($reordered); + $this->_objectManager->get(SessionQuote::class)->setReordered($reordered); $orderController = $this->_objectManager->get( \Magento\Sales\Controller\Adminhtml\Order\Stub\OrderCreateStub::class ); @@ -278,7 +344,7 @@ public function testSyncBetweenQuoteAddresses() $quoteRepository = $this->_objectManager->get(CartRepositoryInterface::class); $quote = $quoteRepository->getActiveForCustomer($customer->getId()); - $session = $this->_objectManager->get(Quote::class); + $session = $this->_objectManager->get(SessionQuote::class); $session->setQuoteId($quote->getId()); $data = [ @@ -314,4 +380,69 @@ public function testSyncBetweenQuoteAddresses() self::assertEquals($data['city'], $shippingAddress->getCity()); self::assertEquals($data['street'], $shippingAddress->getStreet()); } + + /** + * Gets quote entity by reserved order id. + * + * @param string $reservedOrderId + * @return Quote + */ + private function getQuoteById(string $reservedOrderId): Quote + { + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = $this->_objectManager->get(SearchCriteriaBuilder::class); + $searchCriteria = $searchCriteriaBuilder->addFilter('reserved_order_id', $reservedOrderId) + ->create(); + + /** @var CartRepositoryInterface $repository */ + $repository = $this->_objectManager->get(CartRepositoryInterface::class); + $items = $repository->getList($searchCriteria) + ->getItems(); + + return array_pop($items); + } + + /** + * Gets website entity. + * + * @param string $code + * @return WebsiteInterface + * @throws NoSuchEntityException + */ + private function getWebsite(string $code): WebsiteInterface + { + /** @var WebsiteRepositoryInterface $repository */ + $repository = $this->_objectManager->get(WebsiteRepositoryInterface::class); + return $repository->get($code); + } + + /** + * Gets customer entity. + * + * @param string $email + * @param int $websiteId + * @return CustomerInterface + * @throws NoSuchEntityException + * @throws \Magento\Framework\Exception\LocalizedException + */ + private function getCustomer(string $email, int $websiteId): CustomerInterface + { + /** @var CustomerRepositoryInterface $repository */ + $repository = $this->_objectManager->get(CustomerRepositoryInterface::class); + return $repository->get($email, $websiteId); + } + + /** + * Gets store by code. + * + * @param string $code + * @return StoreInterface + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + private function getStore(string $code): StoreInterface + { + /** @var StoreRepositoryInterface $repository */ + $repository = $this->_objectManager->get(StoreRepositoryInterface::class); + return $repository->get($code); + } } diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/websites_different_countries.php b/dev/tests/integration/testsuite/Magento/Store/_files/websites_different_countries.php index 04223d1353314..970b1619f0214 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/websites_different_countries.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/websites_different_countries.php @@ -10,6 +10,7 @@ use Magento\Store\Model\Store; use Magento\CatalogSearch\Model\Indexer\Fulltext as FulltextIndex; use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\Store\Model\Group; $objectManager = Bootstrap::getObjectManager(); //Creating second website with a store. @@ -21,12 +22,23 @@ $website->setData([ 'code' => 'test', 'name' => 'Test Website', - 'default_group_id' => '1', 'is_default' => '0', ]); $website->save(); } +/** + * @var Group $storeGroup + */ +$storeGroup = $objectManager->create(Group::class); +$storeGroup->setCode('some_group') + ->setName('custom store group') + ->setWebsite($website); +$storeGroup->save($storeGroup); + +$website->setDefaultGroupId($storeGroup->getId()); +$website->save($website); + $websiteId = $website->getId(); $store = $objectManager->create(Store::class); $store->load('fixture_second_store', 'code'); From 476f14ff89d6be14d1b3d8c950713c00d5802ec0 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 26 Sep 2018 16:35:20 +0000 Subject: [PATCH 111/812] graphQl-44: refactoring of resolver Signed-off-by: vitaliyboyko <v.boyko@atwix.com> --- .../Resolver/Product/ProductTextAttribute.php | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php index 9c1212667acf3..7649464e2e1ca 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -10,8 +10,7 @@ use Magento\Catalog\Model\Product; use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\FormatList; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\Value; -use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -25,26 +24,18 @@ class ProductTextAttribute implements ResolverInterface */ private $formatList; - /** - * @var ValueFactory - */ - private $valueFactory; - /** * @var string */ private $defaultFormat = 'html'; /** - * @param ValueFactory $valueFactory - * @param FormatList $formatFactory + * @param FormatList $formatList */ public function __construct( - ValueFactory $valueFactory, - FormatList $formatFactory + FormatList $formatList ) { - $this->valueFactory = $valueFactory; - $this->formatList = $formatFactory; + $this->formatList = $formatList; } /** @@ -56,10 +47,9 @@ public function resolve( ResolveInfo $info, array $value = null, array $args = null - ): Value { + ) { if (!isset($value['model'])) { - $result = []; - return $this->valueFactory->create($result); + throw new GraphQlInputException(__('"model" value should be specified')); } /* @var $product Product */ @@ -69,6 +59,6 @@ public function resolve( $format = $this->formatList->create($formatIdentifier); $result = ['content' => $format->getContent($product, $fieldName)]; - return $this->valueFactory->create($result); + return $result; } } From 488c2dc7b58931093fd8e7ca498343b2737e7a5f Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 26 Sep 2018 16:53:33 -0500 Subject: [PATCH 112/812] MAGETWO-71675: Customer can't see available Payment Method for specific country --- .../Mftf/ActionGroup/CheckoutActionGroup.xml | 45 +++++++++++++++ .../Mftf/Section/CheckoutPaymentSection.xml | 1 + .../Mftf/Test/StorefrontGuestCheckoutTest.xml | 57 +++++++++++++++++++ .../view/frontend/web/js/view/shipping.js | 1 + 4 files changed, 104 insertions(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index 32d6ad8667029..eef35abcc978a 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -38,6 +38,51 @@ <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> </actionGroup> + <!-- Guest checkout filling shipping section without region --> + <actionGroup name="GuestCheckoutFillingShippingSectionWithoutRegionActionGroup"> + <arguments> + <argument name="customerVar"/> + <argument name="customerAddressVar"/> + </arguments> + <fillField selector="{{CheckoutShippingSection.email}}" userInput="{{customerVar.email}}" stepKey="enterEmail"/> + <fillField selector="{{CheckoutShippingSection.firstName}}" userInput="{{customerVar.firstname}}" stepKey="enterFirstName"/> + <fillField selector="{{CheckoutShippingSection.lastName}}" userInput="{{customerVar.lastname}}" stepKey="enterLastName"/> + <fillField selector="{{CheckoutShippingSection.street}}" userInput="{{customerAddressVar.street[0]}}" stepKey="enterStreet"/> + <fillField selector="{{CheckoutShippingSection.city}}" userInput="{{customerAddressVar.city}}" stepKey="enterCity"/> + <fillField selector="{{CheckoutShippingSection.postcode}}" userInput="{{customerAddressVar.postcode}}" stepKey="enterPostcode"/> + <selectOption selector="{{CheckoutShippingSection.country}}" userInput="{{customerAddressVar.country_id}}" stepKey="enterCountry"/> + <fillField selector="{{CheckoutShippingSection.telephone}}" userInput="{{customerAddressVar.telephone}}" stepKey="enterTelephone"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <click selector="{{CheckoutShippingSection.firstShippingMethod}}" stepKey="selectFirstShippingMethod"/> + <waitForElement selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> + <waitForElement selector="{{CheckoutPaymentSection.paymentSectionTitle}}" time="30" stepKey="waitForPaymentSectionLoaded"/> + <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> + </actionGroup> + + <!-- Guest checkout filling shipping section with unavailable payments--> + <actionGroup name="GuestCheckoutFillingShippingSectionUnavailablePaymentActionGroup"> + <arguments> + <argument name="customerVar"/> + <argument name="customerAddressVar"/> + </arguments> + <fillField selector="{{CheckoutShippingSection.email}}" userInput="{{customerVar.email}}" stepKey="enterEmail"/> + <fillField selector="{{CheckoutShippingSection.firstName}}" userInput="{{customerVar.firstname}}" stepKey="enterFirstName"/> + <fillField selector="{{CheckoutShippingSection.lastName}}" userInput="{{customerVar.lastname}}" stepKey="enterLastName"/> + <fillField selector="{{CheckoutShippingSection.street}}" userInput="{{customerAddressVar.street[0]}}" stepKey="enterStreet"/> + <fillField selector="{{CheckoutShippingSection.city}}" userInput="{{customerAddressVar.city}}" stepKey="enterCity"/> + <selectOption selector="{{CheckoutShippingSection.region}}" userInput="{{customerAddressVar.state}}" stepKey="selectRegion"/> + <fillField selector="{{CheckoutShippingSection.postcode}}" userInput="{{customerAddressVar.postcode}}" stepKey="enterPostcode"/> + <fillField selector="{{CheckoutShippingSection.telephone}}" userInput="{{customerAddressVar.telephone}}" stepKey="enterTelephone"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <click selector="{{CheckoutShippingSection.firstShippingMethod}}" stepKey="selectFirstShippingMethod"/> + <waitForElement selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> + <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> + <waitForElementVisible selector="{{CheckoutPaymentSection.noQuotes}}" stepKey="waitMessage"/> + <see userInput="No Payment method available." stepKey="checkMessage"/> + </actionGroup> + <!-- Logged in user checkout filling shipping section --> <actionGroup name="LoggedInUserCheckoutFillingShippingSectionActionGroup"> <arguments> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index 7dda1110fd145..846b20ed225dd 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -50,5 +50,6 @@ <element name="shippingAndBillingAddressSame" type="input" selector="#billing-address-same-as-shipping-braintree_cc_vault"/> <element name="addressAction" type="button" selector="//span[text()='{{action}}']" parameterized="true"/> <element name="addressBook" type="button" selector="//a[text()='Address Book']"/> + <element name="noQuotes" type="text" selector=".no-quotes-block"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml index a7b82d54afb30..02cc233acc7bc 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml @@ -68,4 +68,61 @@ <see selector="{{AdminOrderDetailsInformationSection.shippingAddress}}" userInput="{{CustomerAddressSimple.street[0]}}" stepKey="seeAdminOrderShippingAddress"/> <see selector="{{AdminOrderDetailsInformationSection.itemsOrdered}}" userInput="$$createProduct.name$$" stepKey="seeAdminOrderProduct"/> </test> + <test name="StorefrontGuestCheckoutTestWithRestrictedCountriesForPayment"> + <annotations> + <features value="Checkout"/> + <stories value="Checkout flow if payment solutions are not available"/> + <title value="Checkout via Guest Checkout with restricted countries for payment"/> + <description value="Should be able to place an order as a Guest with restricted countries for payment."/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-42653"/> + <group value="checkout"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="ApiSimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <magentoCLI stepKey="allowSpecificValue" command="config:set payment/checkmo/allowspecific 1" /> + <magentoCLI stepKey="specificCountryValue" command="config:set payment/checkmo/specificcountry GB" /> + + </before> + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <magentoCLI stepKey="allowSpecificValue" command="config:set payment/checkmo/allowspecific 0" /> + <magentoCLI stepKey="specificCountryValue" command="config:set payment/checkmo/specificcountry ''" /> + </after> + + <!-- Add product to cart --> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <click selector="{{StorefrontCategoryMainSection.AddToCartBtn}}" stepKey="addToCart"/> + <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> + <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> + <see selector="{{StorefrontMinicartSection.quantity}}" userInput="1" stepKey="seeCartQuantity"/> + + <!-- Go to checkout page --> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="guestGoToCheckoutFromMinicart" /> + + <!-- Fill US Address and verify that no payment available --> + <actionGroup ref="GuestCheckoutFillingShippingSectionUnavailablePaymentActionGroup" stepKey="guestCheckoutFillingShippingSection"> + <argument name="customerVar" value="CustomerEntityOne" /> + <argument name="customerAddressVar" value="CustomerAddressSimple" /> + </actionGroup> + + <!-- Fill UK Address and verify that payment available and checkout successful --> + <click selector="{{CheckoutHeaderSection.shippingMethodStep}}" stepKey="goToShipping" /> + <actionGroup ref="GuestCheckoutFillingShippingSectionWithoutRegionActionGroup" stepKey="guestCheckoutFillingShippingSectionUK"> + <argument name="customerVar" value="CustomerEntityOne" /> + <argument name="customerAddressVar" value="UK_Not_Default_Address" /> + </actionGroup> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="guestSelectCheckMoneyOrderPayment" /> + <actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="guestPlaceorder"> + <argument name="orderNumberMessage" value="CONST.successGuestCheckoutOrderNumberMessage" /> + <argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage" /> + </actionGroup> + </test> </tests> diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js index c0f8b5a45fec9..395d15bc02f36 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js @@ -247,6 +247,7 @@ define([ */ setShippingInformation: function () { if (this.validateShippingInformation()) { + quote.billingAddress(null); checkoutDataResolver.resolveBillingAddress(); setShippingInformationAction().done( function () { From bba7e3525d99eca28f3966af6732b7b41ae01493 Mon Sep 17 00:00:00 2001 From: "Hakobyan, Lusine" <Lusine_Hakobyan@epam.com> Date: Thu, 27 Sep 2018 15:10:36 +0400 Subject: [PATCH 113/812] MAGETWO-91733: Unusual behavior with the persistent shopping cart after the session is expired - Add automated test --- ...ingCartBehaviorAfterSessionExpiredTest.xml | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 app/code/Magento/Persistent/Test/Mftf/Test/CheckShoppingCartBehaviorAfterSessionExpiredTest.xml diff --git a/app/code/Magento/Persistent/Test/Mftf/Test/CheckShoppingCartBehaviorAfterSessionExpiredTest.xml b/app/code/Magento/Persistent/Test/Mftf/Test/CheckShoppingCartBehaviorAfterSessionExpiredTest.xml new file mode 100644 index 0000000000000..c66a2979aa7f5 --- /dev/null +++ b/app/code/Magento/Persistent/Test/Mftf/Test/CheckShoppingCartBehaviorAfterSessionExpiredTest.xml @@ -0,0 +1,57 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CheckShoppingCartBehaviorAfterSessionExpiredTest"> + <annotations> + <features value="Persistent"/> + <stories value="MAGETWO-91733 - Unusual behavior with the persistent shopping cart after the session is expired"/> + <title value="Checking behavior with the persistent shopping cart after the session is expired"/> + <description value="Checking behavior with the persistent shopping cart after the session is expired"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-95118"/> + <group value="persistent"/> + </annotations> + <before> + <!--Enable Persistence--> + <createData entity="PersistentConfigEnabled" stepKey="enablePersistent"/> + <!--Create product--> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!-- Create new customer --> + <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> + <argument name="Customer" value="Simple_US_Customer_NY"/> + </actionGroup> + <!--Add shipping information--> + <actionGroup ref="EnterCustomerAddressInfo" stepKey="enterAddressInfo"> + <argument name="Address" value="US_Address_NY"/> + </actionGroup> + </before> + <after> + <!--Roll back configuration--> + <createData entity="PersistentConfigDefault" stepKey="setDefaultPersistentState"/> + <!--Delete product--> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + </after> + <!-- Add simple product to cart --> + <actionGroup ref="AddSimpleProductToCart" stepKey="addProductToCart1"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> + <actionGroup ref="clickViewAndEditCartFromMiniCart" stepKey="goToShoppingCartFromMinicart"/> + <!--Reset cookies and refresh the page--> + <resetCookie userInput="PHPSESSID" stepKey="resetCookieForCart"/> + <reloadPage stepKey="reloadPage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <!--Check product exists in cart--> + <see userInput="$$createProduct.name$$" stepKey="ProductExistsInCart"/> + </test> +</tests> From 4c76f9a441a564ade8e904cd99eed0827162ff9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antun=20Matanovi=C4=87?= <antun.matanovic@gmail.com> Date: Thu, 27 Sep 2018 13:15:39 +0200 Subject: [PATCH 114/812] save the custom option price when it is 0 --- .../CatalogImportExport/Model/Import/Product/Option.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php index c7eb722050303..fa2853c738624 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php @@ -1794,7 +1794,8 @@ protected function _getSpecificTypeData(array $rowData, $optionTypeId, $defaultS ]; $priceData = false; - if (!empty($rowData[self::COLUMN_ROW_PRICE])) { + $customOptionRowPrice = $rowData[self::COLUMN_ROW_PRICE]; + if (!empty($customOptionRowPrice) || $customOptionRowPrice === '0') { $priceData = [ 'price' => (double)rtrim($rowData[self::COLUMN_ROW_PRICE], '%'), 'price_type' => 'fixed', From 74ca77ca8023516fea3be1c4eb4714d6f63b791b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antun=20Matanovi=C4=87?= <antun.matanovic@gmail.com> Date: Thu, 27 Sep 2018 13:37:51 +0200 Subject: [PATCH 115/812] updated the tests --- .../Magento/CatalogImportExport/Model/Import/ProductTest.php | 2 +- .../Model/Import/_files/product_with_custom_options_new.csv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index c5e704c2434b5..a33d460a50756 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -431,7 +431,7 @@ public function getBehaviorDataProvider(): array 'Append behavior with new product' => [ 'importFile' => 'product_with_custom_options_new.csv', 'sku' => 'simple_new', - 'expectedOptionsQty' => 4, + 'expectedOptionsQty' => 5, ], ]; } diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/product_with_custom_options_new.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/product_with_custom_options_new.csv index 7fe8832cd5804..f276a96cd1d38 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/product_with_custom_options_new.csv +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/product_with_custom_options_new.csv @@ -1,2 +1,2 @@ sku,store_view_code,attribute_set_code,product_type,categories,product_websites,name,description,short_description,weight,product_online,tax_class_name,visibility,price,special_price,special_price_from_date,special_price_to_date,url_key,meta_title,meta_keywords,meta_description,base_image,base_image_label,small_image,small_image_label,thumbnail_image,thumbnail_image_label,created_at,updated_at,new_from_date,new_to_date,display_product_options_in,map_price,msrp_price,map_enabled,gift_message_available,custom_design,custom_design_from,custom_design_to,custom_layout_update,page_layout,product_options_container,msrp_display_actual_price_type,country_of_manufacture,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,related_skus,crosssell_skus,upsell_skus,additional_images,additional_image_labels,hide_from_product_page,custom_options,bundle_price_type,bundle_sku_type,bundle_price_view,bundle_weight_type,bundle_values,associated_skus -simple_new,,Default,simple,,base,"New Product",,,,1,"Taxable Goods","Catalog, Search",10.0000,,,,new-product,"New Product","New Product","New Product ",,,,,,,"2015-10-20 07:05:38","2015-10-20 07:05:38",,,"Block after Info Column",,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100.0000,0.0000,1,0,0,1,1.0000,1,10000.0000,1,1,1.0000,1,1,0,1,1.0000,0,0,0,1,,,,,,,"name=New Radio,type=radio,required=1,price=3.0000,price_type=fixed,sku=4-1-radio,option_title=Option 1|name=New Radio,type=radio,required=1,price=3.0000,price_type=fixed,sku=4-2-radio,option_title=Option 2|name=New Select,type=drop_down,required=1,price=3.0000,price_type=fixed,sku=3-1-select,option_title=Option 1|name=New Select,type=drop_down,required=1,price=3.0000,price_type=fixed,sku=3-2-select,option_title=Option2|name=Test Date and Time Title,type=date_time,required=1,price=2.0000,price_type=fixed,sku=2-date|name=Test Field Title,type=field,required=1,price=0.0000,price_type=fixed,sku=1-text,max_characters=10",,,,,, +simple_new,,Default,simple,,base,"New Product",,,,1,"Taxable Goods","Catalog, Search",10.0000,,,,new-product,"New Product","New Product","New Product ",,,,,,,"2015-10-20 07:05:38","2015-10-20 07:05:38",,,"Block after Info Column",,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",100.0000,0.0000,1,0,0,1,1.0000,1,10000.0000,1,1,1.0000,1,1,0,1,1.0000,0,0,0,1,,,,,,,"name=New Radio,type=radio,required=1,price=3.0000,price_type=fixed,sku=4-1-radio,option_title=Option 1|name=New Radio,type=radio,required=1,price=3.0000,price_type=fixed,sku=4-2-radio,option_title=Option 2|name=New Select,type=drop_down,required=1,price=3.0000,price_type=fixed,sku=3-1-select,option_title=Option 1|name=New Select,type=drop_down,required=1,price=3.0000,price_type=fixed,sku=3-2-select,option_title=Option2|name=Test Date and Time Title,type=date_time,required=1,price=2.0000,price_type=fixed,sku=2-date|name=Test Field Title,type=field,required=1,price=0.0000,price_type=fixed,sku=1-text,max_characters=10|name=New Select With Zero Price,type=drop_down,required=1,price=0,price_type=fixed,sku=3-1-select,option_title=Option 1",,,,,, From 5d5ae032b48280118d8681a30d9d4abd1d2027fb Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Thu, 27 Sep 2018 15:16:51 +0300 Subject: [PATCH 116/812] MAGETWO-91679: Bundled SKUs are being assembled based on the product ID number - Fixed an issue with incorrect genereation of dynamic SKU for bundle products; --- app/code/Magento/Bundle/Model/Product/Type.php | 7 +++++-- .../Bundle/Test/Unit/Model/Product/TypeTest.php | 11 +++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php index 92bada8094c7e..67441cd944c4f 100644 --- a/app/code/Magento/Bundle/Model/Product/Type.php +++ b/app/code/Magento/Bundle/Model/Product/Type.php @@ -308,8 +308,11 @@ public function getSku($product) $selectionIds = $this->serializer->unserialize($customOption->getValue()); if (!empty($selectionIds)) { $selections = $this->getSelectionsByIds($selectionIds, $product); - foreach ($selections->getItems() as $selection) { - $skuParts[] = $selection->getSku(); + foreach ($selectionIds as $selectionId) { + $entity = $selections->getItemByColumnValue('selection_id', $selectionId); + if ($entity->getEntityId()) { + $skuParts[] = $entity->getSku(); + } } } } diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php index 4bbf5641c55d3..1b9cafbe8c198 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php @@ -1595,7 +1595,7 @@ public function testGetSkuWithoutType() ->disableOriginalConstructor() ->getMock(); $selectionItemMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->setMethods(['getSku', '__wakeup']) + ->setMethods(['getSku', 'getEntityId', '__wakeup']) ->disableOriginalConstructor() ->getMock(); @@ -1623,9 +1623,12 @@ public function testGetSkuWithoutType() ->will($this->returnValue($serializeIds)); $selectionMock = $this->getSelectionsByIdsMock($selectionIds, $productMock, 5, 6); $selectionMock->expects(($this->any())) - ->method('getItems') - ->will($this->returnValue([$selectionItemMock])); - $selectionItemMock->expects($this->any()) + ->method('getItemByColumnValue') + ->will($this->returnValue($selectionItemMock)); + $selectionItemMock->expects($this->at(0)) + ->method('getEntityId') + ->will($this->returnValue(1)); + $selectionItemMock->expects($this->once()) ->method('getSku') ->will($this->returnValue($itemSku)); From 27474ec6be80104d0b78231719610dacc5de7f2b Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Tue, 25 Sep 2018 15:17:21 +0300 Subject: [PATCH 117/812] MAGETWO-91764: Frontend base url https results in admin too many redirects #8800 - Fixed an issue with cyclic redirects when using 'custom admin url' and 'secure urls in admin'. --- .../Magento/Backend/Model/AdminPathConfig.php | 38 ++++++++-------- .../Test/Unit/Model/AdminPathConfigTest.php | 44 +++++++++++++------ 2 files changed, 49 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/Backend/Model/AdminPathConfig.php b/app/code/Magento/Backend/Model/AdminPathConfig.php index e7338adca4a2a..0e77835a5134c 100644 --- a/app/code/Magento/Backend/Model/AdminPathConfig.php +++ b/app/code/Magento/Backend/Model/AdminPathConfig.php @@ -48,10 +48,7 @@ public function __construct( } /** - * {@inheritdoc} - * - * @param \Magento\Framework\App\RequestInterface $request - * @return string + * @inheritdoc */ public function getCurrentSecureUrl(\Magento\Framework\App\RequestInterface $request) { @@ -59,28 +56,29 @@ public function getCurrentSecureUrl(\Magento\Framework\App\RequestInterface $req } /** - * {@inheritdoc} - * - * @param string $path - * @return bool + * @inheritdoc */ public function shouldBeSecure($path) { - return parse_url( - (string)$this->coreConfig->getValue(Store::XML_PATH_UNSECURE_BASE_URL, 'default'), - PHP_URL_SCHEME - ) === 'https' - || $this->backendConfig->isSetFlag(Store::XML_PATH_SECURE_IN_ADMINHTML) - && parse_url( - (string)$this->coreConfig->getValue(Store::XML_PATH_SECURE_BASE_URL, 'default'), - PHP_URL_SCHEME - ) === 'https'; + $baseUrl = (string)$this->coreConfig->getValue(Store::XML_PATH_UNSECURE_BASE_URL, 'default'); + if (parse_url($baseUrl, PHP_URL_SCHEME) === 'https') { + return true; + } + + if ($this->backendConfig->isSetFlag(Store::XML_PATH_SECURE_IN_ADMINHTML)) { + if ($this->backendConfig->isSetFlag('admin/url/use_custom')) { + $adminBaseUrl = (string)$this->coreConfig->getValue('admin/url/custom', 'default'); + } else { + $adminBaseUrl = (string)$this->coreConfig->getValue(Store::XML_PATH_SECURE_BASE_URL, 'default'); + } + return parse_url($adminBaseUrl, PHP_URL_SCHEME) === 'https'; + } + + return false; } /** - * {@inheritdoc} - * - * @return string + * @inheritdoc */ public function getDefaultPath() { diff --git a/app/code/Magento/Backend/Test/Unit/Model/AdminPathConfigTest.php b/app/code/Magento/Backend/Test/Unit/Model/AdminPathConfigTest.php index 4911dc1e9968e..b373459b7864d 100644 --- a/app/code/Magento/Backend/Test/Unit/Model/AdminPathConfigTest.php +++ b/app/code/Magento/Backend/Test/Unit/Model/AdminPathConfigTest.php @@ -76,17 +76,35 @@ public function testGetCurrentSecureUrl() * @param $unsecureBaseUrl * @param $useSecureInAdmin * @param $secureBaseUrl + * @param $useCustomUrl + * @param $customUrl * @param $expected * @dataProvider shouldBeSecureDataProvider */ - public function testShouldBeSecure($unsecureBaseUrl, $useSecureInAdmin, $secureBaseUrl, $expected) - { - $coreConfigValueMap = [ + public function testShouldBeSecure( + $unsecureBaseUrl, + $useSecureInAdmin, + $secureBaseUrl, + $useCustomUrl, + $customUrl, + $expected + ) { + $coreConfigValueMap = $this->returnValueMap([ [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL, 'default', null, $unsecureBaseUrl], [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL, 'default', null, $secureBaseUrl], - ]; - $this->coreConfig->expects($this->any())->method('getValue')->will($this->returnValueMap($coreConfigValueMap)); - $this->backendConfig->expects($this->any())->method('isSetFlag')->willReturn($useSecureInAdmin); + ['admin/url/custom', 'default', null, $customUrl], + ]); + $backendConfigFlagsMap = $this->returnValueMap([ + [\Magento\Store\Model\Store::XML_PATH_SECURE_IN_ADMINHTML, $useSecureInAdmin], + ['admin/url/use_custom', $useCustomUrl], + ]); + $this->coreConfig->expects($this->atLeast(1))->method('getValue') + ->will($coreConfigValueMap); + $this->coreConfig->expects($this->atMost(2))->method('getValue') + ->will($coreConfigValueMap); + + $this->backendConfig->expects($this->atMost(2))->method('isSetFlag') + ->will($backendConfigFlagsMap); $this->assertEquals($expected, $this->adminPathConfig->shouldBeSecure('')); } @@ -96,13 +114,13 @@ public function testShouldBeSecure($unsecureBaseUrl, $useSecureInAdmin, $secureB public function shouldBeSecureDataProvider() { return [ - ['http://localhost/', false, 'default', false], - ['http://localhost/', true, 'default', false], - ['https://localhost/', false, 'default', true], - ['https://localhost/', true, 'default', true], - ['http://localhost/', false, 'https://localhost/', false], - ['http://localhost/', true, 'https://localhost/', true], - ['https://localhost/', true, 'https://localhost/', true], + ['http://localhost/', false, 'default', false, '', false], + ['http://localhost/', true, 'default', false, '', false], + ['https://localhost/', false, 'default', false, '', true], + ['https://localhost/', true, 'default', false, '', true], + ['http://localhost/', false, 'https://localhost/', false, '', false], + ['http://localhost/', true, 'https://localhost/', false, '', true], + ['https://localhost/', true, 'https://localhost/', false, '', true], ]; } From 3d34a3c74d78929d76bdaa3944b6e371be147d09 Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Thu, 27 Sep 2018 17:03:01 +0300 Subject: [PATCH 118/812] MAGETWO-94989: [2.3] Magnifier function does not disappear after mouse-off the image from the bottom --- lib/web/magnifier/magnifier.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/web/magnifier/magnifier.js b/lib/web/magnifier/magnifier.js index 150c8adf0b22b..55646aa9b4af2 100644 --- a/lib/web/magnifier/magnifier.js +++ b/lib/web/magnifier/magnifier.js @@ -554,6 +554,15 @@ thumbObj.src = thumb.src; } + /** + * Hide magnifier when mouse exceeds image bounds. + */ + function onMouseLeave() { + onThumbLeave(); + isOverThumb = false; + $magnifierPreview.addClass(MagnifyCls.magnifyHidden); + } + function onMousemove(e) { pos.x = e.clientX; pos.y = e.clientY; @@ -564,20 +573,13 @@ isOverThumb = inBounds; } - if (inBounds && isOverThumb) { - if(gMode === 'outside'){ - $magnifierPreview.removeClass(MagnifyCls.magnifyHidden); - } + if (inBounds && isOverThumb && gMode === 'outside') { + $magnifierPreview.removeClass(MagnifyCls.magnifyHidden); move(); - } else { - onThumbLeave(); - isOverThumb = false; - $magnifierPreview.addClass(MagnifyCls.magnifyHidden); } } function onScroll() { - if (curThumb !== null) { setThumbData(curThumb, magnifierOptions); } @@ -589,6 +591,8 @@ }); $box.on('mousemove', onMousemove); + $box.on('mouseleave', onMouseLeave); + _init($box, customUserOptions); } }(jQuery)); From 32058c748731348e7d38cffa7a6c56113e17b3d8 Mon Sep 17 00:00:00 2001 From: David Alger <davidmalger@gmail.com> Date: Thu, 27 Sep 2018 10:44:27 -0500 Subject: [PATCH 119/812] Update colinmollenhour/cache-backend-redis from version 1.10.5 to 1.10.6 See colinmollenhour/Cm_Cache_Backend_Redis#134 for details on updates to library --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index e2a646275d98b..dfd7bfb5aa9ec 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "lib-libxml": "*", "braintree/braintree_php": "3.35.0", "colinmollenhour/cache-backend-file": "~1.4.1", - "colinmollenhour/cache-backend-redis": "1.10.5", + "colinmollenhour/cache-backend-redis": "1.10.6", "colinmollenhour/credis": "1.10.0", "colinmollenhour/php-redis-session-abstract": "~1.4.0", "composer/composer": "^1.6", diff --git a/composer.lock b/composer.lock index 2550f70f0be81..849366434dbf4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "18982aa4d36bcfd22cf073dfb578efdb", + "content-hash": "dcecc6ef5197bb32c59c7ba1f5d136ac", "packages": [ { "name": "braintree/braintree_php", @@ -88,16 +88,16 @@ }, { "name": "colinmollenhour/cache-backend-redis", - "version": "1.10.5", + "version": "1.10.6", "source": { "type": "git", "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis.git", - "reference": "91d949e28d939e607484a4bbf9307cff5afa689b" + "reference": "cc941a5f4cc017e11d3eab9061811ba9583ed6bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_Redis/zipball/91d949e28d939e607484a4bbf9307cff5afa689b", - "reference": "91d949e28d939e607484a4bbf9307cff5afa689b", + "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_Redis/zipball/cc941a5f4cc017e11d3eab9061811ba9583ed6bf", + "reference": "cc941a5f4cc017e11d3eab9061811ba9583ed6bf", "shasum": "" }, "require": { @@ -120,7 +120,7 @@ ], "description": "Zend_Cache backend using Redis with full support for tags.", "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis", - "time": "2018-05-15T16:02:25+00:00" + "time": "2018-09-24T16:02:07+00:00" }, { "name": "colinmollenhour/credis", From 5aab5421697039e56993f84d88e2b6db4a2242da Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 26 Sep 2018 21:12:12 +0300 Subject: [PATCH 120/812] MAGETWO-91517: Cancel and Return link removes billing and shipping address - Provide information from database to set to browser local storage if local storage is empty. --- .../Checkout/Model/DefaultConfigProvider.php | 53 +++++++++++++++++-- .../web/js/model/checkout-data-resolver.js | 13 ++++- .../web/js/view/form/element/email.js | 7 +++ 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php index ea6cdd2e51b4a..fd120f0a37a4b 100644 --- a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php +++ b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php @@ -14,6 +14,7 @@ use Magento\Customer\Model\Session as CustomerSession; use Magento\Customer\Model\Url as CustomerUrlManager; use Magento\Eav\Api\AttributeOptionManagementInterface; +use Magento\Framework\Api\CustomAttributesDataInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Http\Context as HttpContext; use Magento\Framework\App\ObjectManager; @@ -22,9 +23,11 @@ use Magento\Framework\UrlInterface; use Magento\Quote\Api\CartItemRepositoryInterface as QuoteItemRepository; use Magento\Quote\Api\CartTotalRepositoryInterface; +use Magento\Quote\Api\Data\AddressInterface; use Magento\Quote\Api\ShippingMethodManagementInterface as ShippingMethodManager; use Magento\Quote\Model\QuoteIdMaskFactory; use Magento\Store\Model\ScopeInterface; +use Magento\Ui\Component\Form\Element\Multiline; /** * Default Config Provider @@ -272,16 +275,28 @@ public function __construct( * * @return array|mixed * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Framework\Exception\LocalizedException */ public function getConfig() { - $quoteId = $this->checkoutSession->getQuote()->getId(); + $quote = $this->checkoutSession->getQuote(); + $quoteId = $quote->getId(); + $email = $quote->getShippingAddress()->getEmail(); $output['formKey'] = $this->formKey->getFormKey(); $output['customerData'] = $this->getCustomerData(); $output['quoteData'] = $this->getQuoteData(); $output['quoteItemData'] = $this->getQuoteItemData(); $output['isCustomerLoggedIn'] = $this->isCustomerLoggedIn(); $output['selectedShippingMethod'] = $this->getSelectedShippingMethod(); + if ($email && !$this->isCustomerLoggedIn()) { + $shippingAddressFromData = $this->getAddressFromData($quote->getShippingAddress()); + $billingAddressFromData = $this->getAddressFromData($quote->getBillingAddress()); + $output['shippingAddressFromData'] = $shippingAddressFromData; + if ($shippingAddressFromData != $billingAddressFromData) { + $output['billingAddressFromData'] = $billingAddressFromData; + } + $output['validatedEmailValue'] = $email; + } $output['storeCode'] = $this->getStoreCode(); $output['isGuestCheckoutAllowed'] = $this->isGuestCheckoutAllowed(); $output['isCustomerLoginRequired'] = $this->isCustomerLoginRequired(); @@ -293,11 +308,11 @@ public function getConfig() $output['staticBaseUrl'] = $this->getStaticBaseUrl(); $output['priceFormat'] = $this->localeFormat->getPriceFormat( null, - $this->checkoutSession->getQuote()->getQuoteCurrencyCode() + $quote->getQuoteCurrencyCode() ); $output['basePriceFormat'] = $this->localeFormat->getPriceFormat( null, - $this->checkoutSession->getQuote()->getBaseCurrencyCode() + $quote->getBaseCurrencyCode() ); $output['postCodes'] = $this->postCodesConfig->getPostCodes(); $output['imageData'] = $this->imageProvider->getImages($quoteId); @@ -528,6 +543,38 @@ private function getSelectedShippingMethod() return $shippingMethodData; } + /** + * Create address data appropriate to fill checkout address form + * + * @param AddressInterface $address + * @return array + * @throws \Magento\Framework\Exception\LocalizedException + */ + private function getAddressFromData(AddressInterface $address) + { + $addressData = []; + $attributesMetadata = $this->addressMetadata->getAllAttributesMetadata(); + foreach ($attributesMetadata as $attributeMetadata) { + if (!$attributeMetadata->isVisible()) { + continue; + } + $attributeCode = $attributeMetadata->getAttributeCode(); + $attributeData = $address->getData($attributeCode); + if ($attributeData) { + if ($attributeMetadata->getFrontendInput() === Multiline::NAME) { + $attributeData = \is_array($attributeData) ? $attributeData : explode("\n", $attributeData); + $attributeData = (object)$attributeData; + } + if ($attributeMetadata->isUserDefined()) { + $addressData[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES][$attributeCode] = $attributeData; + continue; + } + $addressData[$attributeCode] = $attributeData; + } + } + return $addressData; + } + /** * Retrieve store code * diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 73f4df567903c..25abe3c4ed3a0 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -60,13 +60,18 @@ define([ this.resolveBillingAddress(); } } - }, /** * Resolve shipping address. Used local storage */ resolveShippingAddress: function () { + if (!checkoutData.getShippingAddressFromData() && + window.checkoutConfig.shippingAddressFromData + ) { + checkoutData.setShippingAddressFromData(window.checkoutConfig.shippingAddressFromData); + } + var newCustomerShippingAddress = checkoutData.getNewCustomerShippingAddress(); if (newCustomerShippingAddress) { @@ -196,6 +201,12 @@ define([ * Resolve billing address. Used local storage */ resolveBillingAddress: function () { + if (!checkoutData.getBillingAddressFromData() && + window.checkoutConfig.billingAddressFromData + ) { + checkoutData.setBillingAddressFromData(window.checkoutConfig.billingAddressFromData); + } + var selectedBillingAddress = checkoutData.getSelectedBillingAddress(), newCustomerBillingAddressData = checkoutData.getNewCustomerBillingAddress(); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js index 4a25778e754c7..6c0075fca6d51 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js @@ -17,6 +17,13 @@ define([ ], function ($, Component, ko, customer, checkEmailAvailability, loginAction, quote, checkoutData, fullScreenLoader) { 'use strict'; + if (!checkoutData.getValidatedEmailValue() && + window.checkoutConfig.validatedEmailValue + ) { + checkoutData.setInputFieldEmailValue(window.checkoutConfig.validatedEmailValue); + checkoutData.setValidatedEmailValue(window.checkoutConfig.validatedEmailValue); + } + var validatedEmail = checkoutData.getValidatedEmailValue(); if (validatedEmail && !customer.isLoggedIn()) { From 77ec759a758eb80aceb28a67ab65d46846e38d78 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Thu, 27 Sep 2018 21:14:23 +0300 Subject: [PATCH 121/812] MAGETWO-91640: Scheduled Import of Products fails on error when errors should be skipped - Changed behaviour for "skip-errors" processing during import shceduling --- .../CatalogImportExport/Model/Import/Product.php | 7 +++++-- app/code/Magento/ImportExport/Model/Import.php | 13 +++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index b755d91e403ff..d85c64327be60 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -1623,8 +1623,11 @@ protected function _saveProducts() continue; } if ($this->getErrorAggregator()->hasToBeTerminated()) { - $this->getErrorAggregator()->addRowToSkip($rowNum); - continue; + $validationStrategy = $this->_parameters[Import::FIELD_NAME_VALIDATION_STRATEGY]; + if (ProcessingErrorAggregatorInterface::VALIDATION_STRATEGY_SKIP_ERRORS !== $validationStrategy) { + $this->getErrorAggregator()->addRowToSkip($rowNum); + continue; + } } $rowScope = $this->getRowScope($rowData); diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index b5e8220e0e9b0..064c696ad0a84 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -181,7 +181,7 @@ class Import extends \Magento\ImportExport\Model\AbstractModel * @param Source\Import\Behavior\Factory $behaviorFactory * @param \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry * @param History $importHistoryModel - * @param \Magento\Framework\Stdlib\DateTime\DateTime + * @param \Magento\Framework\Stdlib\DateTime\DateTime $localeDate * @param array $data * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -443,6 +443,8 @@ public function importSource() } /** + * Processing of import. + * * @return bool * @throws \Magento\Framework\Exception\LocalizedException */ @@ -462,6 +464,8 @@ public function isImportAllowed() } /** + * Get error aggregator instance. + * * @return ProcessingErrorAggregatorInterface * @throws \Magento\Framework\Exception\LocalizedException */ @@ -585,6 +589,11 @@ public function validateSource(\Magento\ImportExport\Model\Import\AbstractSource $this->addLogComment($messages); $result = !$errorAggregator->getErrorsCount(); + $validationStrategy = $this->getData(self::FIELD_NAME_VALIDATION_STRATEGY); + if ($validationStrategy === ProcessingErrorAggregatorInterface::VALIDATION_STRATEGY_SKIP_ERRORS) { + $result = true; + } + if ($result) { $this->addLogComment(__('Import data validation is complete.')); } @@ -710,9 +719,9 @@ public function isReportEntityType($entity = null) /** * Create history report * + * @param string $sourceFileRelative * @param string $entity * @param string $extension - * @param string $sourceFileRelative * @param array $result * @return $this * @throws \Magento\Framework\Exception\LocalizedException From 312449eb5672f67dd09f6804f1ddd61e714069d2 Mon Sep 17 00:00:00 2001 From: Aleksey Tsoy <aleksey_tsoy@epam.com> Date: Fri, 28 Sep 2018 13:27:10 +0600 Subject: [PATCH 122/812] MAGETWO-91649: #13513: Magento ignore store-level url_key of child category in URL rewrite process for global scope - Added automated test --- .../ActionGroup/AdminCategoryActionGroup.xml | 24 ++++++- .../StorefrontCategoryActionGroup.xml | 15 +++++ ...iteStoreLevelUrlKeyOfChildCategoryTest.xml | 67 +++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/RewriteStoreLevelUrlKeyOfChildCategoryTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml index 7c04e9bd83d56..b5b69cefff9a6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml @@ -237,8 +237,30 @@ </arguments> <amOnPage url="{{AdminCategoryPage.page}}" stepKey="amOnCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> - <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(Category.Name)}}" stepKey="navigateToCreatedCategory" /> + <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="expandAll"/> <waitForPageLoad stepKey="waitForPageLoad2"/> + <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(Category.Name)}}" stepKey="navigateToCreatedCategory" /> <waitForLoadingMaskToDisappear stepKey="waitForSpinner" /> </actionGroup> + + <actionGroup name="ChangeSeoUrlKey"> + <arguments> + <argument name="value" type="string"/> + </arguments> + <click selector="{{AdminCategorySEOSection.SectionHeader}}" stepKey="openSeoSection"/> + <fillField selector="{{AdminCategorySEOSection.UrlKeyInput}}" userInput="{{value}}" stepKey="enterURLKey"/> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="assertSuccessMessage"/> + </actionGroup> + + <actionGroup name="ChangeSeoUrlKeyForSubCategory"> + <arguments> + <argument name="value" type="string"/> + </arguments> + <click selector="{{AdminCategorySEOSection.SectionHeader}}" stepKey="openSeoSection"/> + <uncheckOption selector="{{AdminCategorySEOSection.UrlKeyDefaultValueCheckbox}}" stepKey="uncheckDefaultValue"/> + <fillField selector="{{AdminCategorySEOSection.UrlKeyInput}}" userInput="{{value}}" stepKey="enterURLKey"/> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="assertSuccessMessage"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml index 4376e78242fbd..a8256b2d55937 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml @@ -50,4 +50,19 @@ <click selector="{{StorefrontCategoryMainSection.modeListButton}}" stepKey="switchCategoryViewToListMode"/> <waitForElement selector="{{StorefrontCategoryMainSection.CategoryTitle}}" time="30" stepKey="waitForCategoryReload"/> </actionGroup> + + <actionGroup name="GoToSubCategoryPage"> + <arguments> + <argument name="parentCategory"/> + <argument name="subCategory"/> + <argument name="urlPath" type="string"/> + </arguments> + <moveMouseOver selector="{{StorefrontHeaderSection.NavigationCategoryByName(parentCategory.name)}}" stepKey="moveMouseOnMainCategory"/> + <waitForElementVisible selector="{{StorefrontHeaderSection.NavigationCategoryByName(subCategory.name)}}" stepKey="waitForSubCategoryVisible"/> + <click selector="{{StorefrontHeaderSection.NavigationCategoryByName(subCategory.name)}}" stepKey="goToCategory"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <seeInCurrentUrl url="{{urlPath}}.html" stepKey="checkUrl"/> + <seeInTitle userInput="{{subCategory.name}}" stepKey="assertCategoryNameInTitle"/> + <see userInput="{{subCategory.name}}" selector="{{StorefrontCategoryMainSection.CategoryTitle}}" stepKey="assertCategoryName"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/RewriteStoreLevelUrlKeyOfChildCategoryTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/RewriteStoreLevelUrlKeyOfChildCategoryTest.xml new file mode 100644 index 0000000000000..67870c51140a6 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/RewriteStoreLevelUrlKeyOfChildCategoryTest.xml @@ -0,0 +1,67 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="RewriteStoreLevelUrlKeyOfChildCategoryTest"> + <annotations> + <title value="Rewriting Store-level URL key of child category"/> + <stories value="MAGETWO-91649: #13513: Magento ignore store-level url_key of child category in URL rewrite process for global scope"/> + <description value="Rewriting Store-level URL key of child category"/> + <features value="CatalogUrlRewrite"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-94934"/> + <group value="CatalogUrlRewrite"/> + </annotations> + + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView" /> + + <createData entity="_defaultCategory" stepKey="defaultCategory"/> + <createData entity="SubCategoryWithParent" stepKey="subCategory"> + <requiredEntity createDataKey="defaultCategory"/> + </createData> + </before> + + <actionGroup ref="navigateToCreatedCategory" stepKey="navigateToCreatedSubCategory"> + <argument name="Category" value="$$subCategory$$"/> + </actionGroup> + + <actionGroup ref="AdminSwitchStoreViewActionGroup" stepKey="AdminSwitchStoreViewForSubCategory"/> + + <actionGroup ref="ChangeSeoUrlKeyForSubCategory" stepKey="changeSeoUrlKeyForSubCategory"> + <argument name="value" value="bags-second"/> + </actionGroup> + + <actionGroup ref="navigateToCreatedCategory" stepKey="navigateToCreatedDefaultCategory"> + <argument name="Category" value="$$defaultCategory$$"/> + </actionGroup> + + <actionGroup ref="ChangeSeoUrlKey" stepKey="changeSeoUrlKeyForDefaultCategory"> + <argument name="value" value="gear-global"/> + </actionGroup> + + <amOnPage url="{{StorefrontHomePage.url}}" stepKey="goToStorefrontPage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + + <actionGroup ref="StorefrontSwitchStoreViewActionGroup" stepKey="storefrontSwitchStoreView"/> + + <actionGroup ref="GoToSubCategoryPage" stepKey="goToSubCategoryPage"> + <argument name="parentCategory" value="$$defaultCategory$$"/> + <argument name="subCategory" value="$$subCategory$$"/> + <argument name="urlPath" value="gear-global/bags-second"/> + </actionGroup> + + <after> + <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreView"/> + <actionGroup ref="logout" stepKey="logout"/> + + <deleteData createDataKey="subCategory" stepKey="deleteSubCategory"/> + <deleteData createDataKey="defaultCategory" stepKey="deleteNewRootCategory"/> + </after> + </test> +</tests> From defc2c525c5e1f6df965f5b8460648b3bff5653a Mon Sep 17 00:00:00 2001 From: Yevhen Sentiabov <isentiabov@magento.com> Date: Fri, 28 Sep 2018 11:49:52 +0300 Subject: [PATCH 123/812] MAGETWO-91610: [2.3] Billing Address in Braintree PayPal response is absent - Added check if a billing address is returned by Braintree --- .../Model/Paypal/Helper/QuoteUpdater.php | 2 +- .../Model/Paypal/Helper/QuoteUpdaterTest.php | 214 +++++++++--------- 2 files changed, 107 insertions(+), 109 deletions(-) diff --git a/app/code/Magento/Braintree/Model/Paypal/Helper/QuoteUpdater.php b/app/code/Magento/Braintree/Model/Paypal/Helper/QuoteUpdater.php index fe5895541543d..aa23fa767d1ed 100644 --- a/app/code/Magento/Braintree/Model/Paypal/Helper/QuoteUpdater.php +++ b/app/code/Magento/Braintree/Model/Paypal/Helper/QuoteUpdater.php @@ -148,7 +148,7 @@ private function updateBillingAddress(Quote $quote, array $details) { $billingAddress = $quote->getBillingAddress(); - if ($this->config->isRequiredBillingAddress()) { + if ($this->config->isRequiredBillingAddress() && !empty($details['billingAddress'])) { $this->updateAddressData($billingAddress, $details['billingAddress']); } else { $this->updateAddressData($billingAddress, $details['shippingAddress']); diff --git a/app/code/Magento/Braintree/Test/Unit/Model/Paypal/Helper/QuoteUpdaterTest.php b/app/code/Magento/Braintree/Test/Unit/Model/Paypal/Helper/QuoteUpdaterTest.php index 62452228b6186..a2b5380d2884b 100644 --- a/app/code/Magento/Braintree/Test/Unit/Model/Paypal/Helper/QuoteUpdaterTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Model/Paypal/Helper/QuoteUpdaterTest.php @@ -3,23 +3,24 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Braintree\Test\Unit\Model\Paypal\Helper; -use Magento\Quote\Model\Quote; -use Magento\Quote\Model\Quote\Address; -use Magento\Quote\Model\Quote\Payment; -use Magento\Quote\Api\CartRepositoryInterface; -use Magento\Braintree\Model\Ui\PayPal\ConfigProvider; -use Magento\Braintree\Observer\DataAssignObserver; use Magento\Braintree\Gateway\Config\PayPal\Config; use Magento\Braintree\Model\Paypal\Helper\QuoteUpdater; +use Magento\Braintree\Model\Ui\PayPal\ConfigProvider; +use Magento\Braintree\Observer\DataAssignObserver; +use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Api\Data\CartExtensionInterface; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\Quote\Address; +use Magento\Quote\Model\Quote\Payment; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class QuoteUpdaterTest * - * @see \Magento\Braintree\Model\Paypal\Helper\QuoteUpdater - * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class QuoteUpdaterTest extends \PHPUnit\Framework\TestCase @@ -27,24 +28,24 @@ class QuoteUpdaterTest extends \PHPUnit\Framework\TestCase const TEST_NONCE = '3ede7045-2aea-463e-9754-cd658ffeeb48'; /** - * @var Config|\PHPUnit_Framework_MockObject_MockObject + * @var Config|MockObject */ - private $configMock; + private $config; /** - * @var CartRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + * @var CartRepositoryInterface|MockObject */ - private $quoteRepositoryMock; + private $quoteRepository; /** - * @var Address|\PHPUnit_Framework_MockObject_MockObject + * @var Address|MockObject */ - private $billingAddressMock; + private $billingAddress; /** - * @var Address|\PHPUnit_Framework_MockObject_MockObject + * @var Address|MockObject */ - private $shippingAddressMock; + private $shippingAddress; /** * @var QuoteUpdater @@ -52,17 +53,17 @@ class QuoteUpdaterTest extends \PHPUnit\Framework\TestCase private $quoteUpdater; /** - * @return void + * @inheritdoc */ protected function setUp() { - $this->configMock = $this->getMockBuilder(Config::class) + $this->config = $this->getMockBuilder(Config::class) ->disableOriginalConstructor() ->getMock(); - $this->quoteRepositoryMock = $this->getMockBuilder(CartRepositoryInterface::class) + $this->quoteRepository = $this->getMockBuilder(CartRepositoryInterface::class) ->getMockForAbstractClass(); - $this->billingAddressMock = $this->getMockBuilder(Address::class) + $this->billingAddress = $this->getMockBuilder(Address::class) ->setMethods( [ 'setLastname', @@ -77,9 +78,10 @@ protected function setUp() 'setShouldIgnoreValidation', 'getEmail' ] - )->disableOriginalConstructor() + ) + ->disableOriginalConstructor() ->getMock(); - $this->shippingAddressMock = $this->getMockBuilder(Address::class) + $this->shippingAddress = $this->getMockBuilder(Address::class) ->setMethods( [ 'setLastname', @@ -93,61 +95,61 @@ protected function setUp() 'setPostcode', 'setShouldIgnoreValidation' ] - )->disableOriginalConstructor() + ) + ->disableOriginalConstructor() ->getMock(); $this->quoteUpdater = new QuoteUpdater( - $this->configMock, - $this->quoteRepositoryMock + $this->config, + $this->quoteRepository ); } /** - * @return void + * Checks if quote details can be update by the response from Braintree. + * * @throws \Magento\Framework\Exception\LocalizedException */ - public function testExecute() + public function testExecute(): void { $details = $this->getDetails(); - $quoteMock = $this->getQuoteMock(); - $paymentMock = $this->getPaymentMock(); + $quote = $this->getQuoteMock(); + $payment = $this->getPaymentMock(); - $quoteMock->expects(self::once()) - ->method('getPayment') - ->willReturn($paymentMock); + $quote->method('getPayment') + ->willReturn($payment); - $paymentMock->expects(self::once()) - ->method('setMethod') + $payment->method('setMethod') ->with(ConfigProvider::PAYPAL_CODE); - $paymentMock->expects(self::once()) - ->method('setAdditionalInformation') + $payment->method('setAdditionalInformation') ->with(DataAssignObserver::PAYMENT_METHOD_NONCE, self::TEST_NONCE); - $this->updateQuoteStep($quoteMock, $details); + $this->updateQuoteStep($quote, $details); - $this->quoteUpdater->execute(self::TEST_NONCE, $details, $quoteMock); + $this->quoteUpdater->execute(self::TEST_NONCE, $details, $quote); } /** + * Disables quote's addresses validation. + * * @return void */ - private function disabledQuoteAddressValidationStep() + private function disabledQuoteAddressValidationStep(): void { - $this->billingAddressMock->expects(self::once()) - ->method('setShouldIgnoreValidation') + $this->billingAddress->method('setShouldIgnoreValidation') ->with(true); - $this->shippingAddressMock->expects(self::once()) - ->method('setShouldIgnoreValidation') + $this->shippingAddress->method('setShouldIgnoreValidation') ->with(true); - $this->billingAddressMock->expects(self::once()) - ->method('getEmail') + $this->billingAddress->method('getEmail') ->willReturn('bt_buyer_us@paypal.com'); } /** + * Gets quote's details. + * * @return array */ - private function getDetails() + private function getDetails(): array { return [ 'email' => 'bt_buyer_us@paypal.com', @@ -177,54 +179,51 @@ private function getDetails() } /** + * Updates shipping address details. + * * @param array $details */ - private function updateShippingAddressStep(array $details) + private function updateShippingAddressStep(array $details): void { - $this->shippingAddressMock->expects(self::once()) - ->method('setLastname') + $this->shippingAddress->method('setLastname') ->with($details['lastName']); - $this->shippingAddressMock->expects(self::once()) - ->method('setFirstname') + $this->shippingAddress->method('setFirstname') ->with($details['firstName']); - $this->shippingAddressMock->expects(self::once()) - ->method('setEmail') + $this->shippingAddress->method('setEmail') ->with($details['email']); - $this->shippingAddressMock->expects(self::once()) - ->method('setCollectShippingRates') + $this->shippingAddress->method('setCollectShippingRates') ->with(true); - $this->updateAddressDataStep($this->shippingAddressMock, $details['shippingAddress']); + $this->updateAddressDataStep($this->shippingAddress, $details['shippingAddress']); } /** - * @param \PHPUnit_Framework_MockObject_MockObject $addressMock + * Updates address details. + * + * @param MockObject $address * @param array $addressData */ - private function updateAddressDataStep(\PHPUnit_Framework_MockObject_MockObject $addressMock, array $addressData) + private function updateAddressDataStep(MockObject $address, array $addressData): void { - $addressMock->expects(self::once()) - ->method('setStreet') + $address->method('setStreet') ->with([$addressData['streetAddress'], $addressData['extendedAddress']]); - $addressMock->expects(self::once()) - ->method('setCity') + $address->method('setCity') ->with($addressData['locality']); - $addressMock->expects(self::once()) - ->method('setRegionCode') + $address->method('setRegionCode') ->with($addressData['region']); - $addressMock->expects(self::once()) - ->method('setCountryId') + $address->method('setCountryId') ->with($addressData['countryCodeAlpha2']); - $addressMock->expects(self::once()) - ->method('setPostcode') + $address->method('setPostcode') ->with($addressData['postalCode']); } /** - * @param \PHPUnit_Framework_MockObject_MockObject $quoteMock + * Updates quote's address details. + * + * @param MockObject $quoteMock * @param array $details */ - private function updateQuoteAddressStep(\PHPUnit_Framework_MockObject_MockObject $quoteMock, array $details) + private function updateQuoteAddressStep(MockObject $quoteMock, array $details): void { $quoteMock->expects(self::exactly(2)) ->method('getIsVirtual') @@ -235,64 +234,61 @@ private function updateQuoteAddressStep(\PHPUnit_Framework_MockObject_MockObject } /** + * Updates billing address details. + * * @param array $details */ - private function updateBillingAddressStep(array $details) + private function updateBillingAddressStep(array $details): void { - $this->configMock->expects(self::once()) - ->method('isRequiredBillingAddress') + $this->config->method('isRequiredBillingAddress') ->willReturn(true); - $this->updateAddressDataStep($this->billingAddressMock, $details['billingAddress']); + $this->updateAddressDataStep($this->billingAddress, $details['billingAddress']); - $this->billingAddressMock->expects(self::once()) - ->method('setLastname') + $this->billingAddress->method('setLastname') ->with($details['lastName']); - $this->billingAddressMock->expects(self::once()) - ->method('setFirstname') + $this->billingAddress->method('setFirstname') ->with($details['firstName']); - $this->billingAddressMock->expects(self::once()) - ->method('setEmail') + $this->billingAddress->method('setEmail') ->with($details['email']); } /** - * @param \PHPUnit_Framework_MockObject_MockObject $quoteMock + * Updates quote details. + * + * @param MockObject $quote * @param array $details */ - private function updateQuoteStep(\PHPUnit_Framework_MockObject_MockObject $quoteMock, array $details) + private function updateQuoteStep(MockObject $quote, array $details): void { - $quoteMock->expects(self::once()) - ->method('setMayEditShippingAddress') + $quote->method('setMayEditShippingAddress') ->with(false); - $quoteMock->expects(self::once()) - ->method('setMayEditShippingMethod') + $quote->method('setMayEditShippingMethod') ->with(true); - $quoteMock->expects(self::exactly(2)) - ->method('getShippingAddress') - ->willReturn($this->shippingAddressMock); - $quoteMock->expects(self::exactly(2)) + $quote->method('getShippingAddress') + ->willReturn($this->shippingAddress); + $quote->expects(self::exactly(2)) ->method('getBillingAddress') - ->willReturn($this->billingAddressMock); + ->willReturn($this->billingAddress); - $this->updateQuoteAddressStep($quoteMock, $details); + $this->updateQuoteAddressStep($quote, $details); $this->disabledQuoteAddressValidationStep(); - $quoteMock->expects(self::once()) - ->method('collectTotals'); + $quote->method('collectTotals'); - $this->quoteRepositoryMock->expects(self::once()) - ->method('save') - ->with($quoteMock); + $this->quoteRepository->method('save') + ->with($quote); } /** - * @return Quote|\PHPUnit_Framework_MockObject_MockObject + * Creates a mock for Quote object. + * + * @return Quote|MockObject */ - private function getQuoteMock() + private function getQuoteMock(): MockObject { - $quoteMock = $this->getMockBuilder(Quote::class) + $quote = $this->getMockBuilder(Quote::class) ->setMethods( [ 'getIsVirtual', @@ -304,25 +300,27 @@ private function getQuoteMock() 'getBillingAddress', 'getExtensionAttributes' ] - )->disableOriginalConstructor() + ) + ->disableOriginalConstructor() ->getMock(); - $cartExtensionMock = $this->getMockBuilder(CartExtensionInterface::class) + $cartExtension = $this->getMockBuilder(CartExtensionInterface::class) ->setMethods(['setShippingAssignments']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $quoteMock->expects(self::any()) - ->method('getExtensionAttributes') - ->willReturn($cartExtensionMock); + $quote->method('getExtensionAttributes') + ->willReturn($cartExtension); - return $quoteMock; + return $quote; } /** - * @return Payment|\PHPUnit_Framework_MockObject_MockObject + * Creates a mock for Payment object. + * + * @return Payment|MockObject */ - private function getPaymentMock() + private function getPaymentMock(): MockObject { return $this->getMockBuilder(Payment::class) ->disableOriginalConstructor() From f3772212cdc4a7eb34ed7e85e274a0774b6c51de Mon Sep 17 00:00:00 2001 From: Yurii Borysov <yurii_borysov@epam.com> Date: Fri, 28 Sep 2018 14:42:08 +0300 Subject: [PATCH 124/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Update sorting logic - Add sorting widget --- .../Product/Form/Modifier/GroupedTest.php | 2 + .../Product/Form/Modifier/Grouped.php | 34 ++- .../adminhtml/web/css/grouped-product.css | 37 ++++ .../adminhtml/web/js/grouped-product-grid.js | 209 ++++++++++++++++++ .../web/template/components/position.html | 19 ++ 5 files changed, 295 insertions(+), 6 deletions(-) create mode 100644 app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js create mode 100644 app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GroupedTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GroupedTest.php index 6ef87117deae2..327b47d4a75d8 100644 --- a/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GroupedTest.php +++ b/app/code/Magento/GroupedProduct/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GroupedTest.php @@ -34,6 +34,7 @@ class GroupedTest extends AbstractModifierTest const LINKED_PRODUCT_NAME = 'linked'; const LINKED_PRODUCT_QTY = '0'; const LINKED_PRODUCT_POSITION = 1; + const LINKED_PRODUCT_POSITION_CALCULATED = 1; const LINKED_PRODUCT_PRICE = '1'; /** @@ -212,6 +213,7 @@ public function testModifyData() 'price' => null, 'qty' => self::LINKED_PRODUCT_QTY, 'position' => self::LINKED_PRODUCT_POSITION, + 'positionCalculated' => self::LINKED_PRODUCT_POSITION_CALCULATED, 'thumbnail' => null, 'type_id' => null, 'status' => null, diff --git a/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php b/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php index 2d1a1d19757e2..57d9bc78aaf28 100644 --- a/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php +++ b/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php @@ -133,7 +133,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -143,12 +143,17 @@ public function modifyData(array $data) if ($modelId) { $storeId = $this->locator->getStore()->getId(); $data[$product->getId()]['links'][self::LINK_TYPE] = []; - foreach ($this->productLinkRepository->getList($product) as $linkItem) { + $linkedItems = $this->productLinkRepository->getList($product); + usort($linkedItems, function ($a, $b) { + return $a->getPosition() <=> $b->getPosition(); + }); + foreach ($linkedItems as $index => $linkItem) { if ($linkItem->getLinkType() !== self::LINK_TYPE) { continue; } /** @var \Magento\Catalog\Api\Data\ProductInterface $linkedProduct */ $linkedProduct = $this->productRepository->get($linkItem->getLinkedProductSku(), false, $storeId); + $linkItem->setPosition($index); $data[$modelId]['links'][self::LINK_TYPE][] = $this->fillData($linkedProduct, $linkItem); } $data[$modelId][self::DATA_SOURCE_DEFAULT]['current_store_id'] = $storeId; @@ -175,6 +180,7 @@ protected function fillData(ProductInterface $linkedProduct, ProductLinkInterfac 'price' => $currency->toCurrency(sprintf("%f", $linkedProduct->getPrice())), 'qty' => $linkItem->getExtensionAttributes()->getQty(), 'position' => $linkItem->getPosition(), + 'positionCalculated' => $linkItem->getPosition(), 'thumbnail' => $this->imageHelper->init($linkedProduct, 'product_listing_thumbnail')->getUrl(), 'type_id' => $linkedProduct->getTypeId(), 'status' => $this->status->getOptionText($linkedProduct->getStatus()), @@ -185,7 +191,7 @@ protected function fillData(ProductInterface $linkedProduct, ProductLinkInterfac } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyMeta(array $meta) { @@ -454,7 +460,7 @@ protected function getGrid() 'label' => null, 'renderDefaultRecord' => false, 'template' => 'ui/dynamic-rows/templates/grid', - 'component' => 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid', + 'component' => 'Magento_GroupedProduct/js/grouped-product-grid', 'addButton' => false, 'itemTemplate' => 'record', 'dataScope' => 'data.links', @@ -555,6 +561,22 @@ protected function fillMeta() ], ], ], + 'positionCalculated' => [ + 'arguments' => [ + 'data' => [ + 'config' => [ + 'label' => __('Position'), + 'dataType' => Form\Element\DataType\Number::NAME, + 'formElement' => Form\Element\Input::NAME, + 'componentType' => Form\Field::NAME, + 'elementTmpl' => 'Magento_GroupedProduct/components/position', + 'sortOrder' => 90, + 'fit' => true, + 'dataScope' => 'positionCalculated' + ], + ], + ], + ], 'actionDelete' => [ 'arguments' => [ 'data' => [ @@ -563,7 +585,7 @@ protected function fillMeta() 'componentType' => 'actionDelete', 'dataType' => Form\Element\DataType\Text::NAME, 'label' => __('Actions'), - 'sortOrder' => 90, + 'sortOrder' => 100, 'fit' => true, ], ], @@ -577,7 +599,7 @@ protected function fillMeta() 'formElement' => Form\Element\Input::NAME, 'componentType' => Form\Field::NAME, 'dataScope' => 'position', - 'sortOrder' => 100, + 'sortOrder' => 110, 'visible' => false, ], ], diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css b/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css index 3d723387d23b0..1916f222a499b 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css @@ -66,3 +66,40 @@ overflow: hidden; text-overflow: ellipsis; } + + +.position { + width:90px; +} + +.icon-rearrange-position > span { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +.icon-forward, +.icon-backward { + -webkit-font-smoothing: antialiased; + font-family: 'Admin Icons'; + font-size: 17px; + speak: none; +} + +.position-widget-input { + text-align: center; + width: 40px; +} + +.icon-forward:before { + content: '\e618'; +} + +.icon-backward:before { + content: '\e619'; +} \ No newline at end of file diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js new file mode 100644 index 0000000000000..0a585eb92958d --- /dev/null +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -0,0 +1,209 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'underscore', + 'uiRegistry', + 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid' +], function (_, registry, dynamicRowsGrid) { + 'use strict'; + return dynamicRowsGrid.extend({ + + /** + * Set max element position + * + * @param {Number} position - element position + * @param {Object} elem - instance + */ + setMaxPosition: function (position, elem) { + + if (position || position === 0) { + this.checkMaxPosition(position); + this.sort(position, elem); + if (~~position === this.maxPosition && ~~position > this.getDefaultPageBoundary() + 1) { + this.shiftNextPagesPositions(position); + } + } else { + this.maxPosition += 1; + } + }, + + /** + * Shift positions for next page elements + * + * @param position + */ + shiftNextPagesPositions: function (position) { + console.log("todo: shifting positions to right on next pages related data"); + }, + + + /** + * Update position for element after position from another page is entered + * + * @param data + * @param event + */ + updateGridPosition: function (data, event) { + var inputValue = ~~event.target.value, + recordData = this.recordData(), + record, + updatedRecord; + + record = this.elems().find(function (obj) { + return obj.dataScope === data.parentScope + }).data(); + + if (inputValue === ~~record.positionCalculated) { + return false; + } + + this.elems([]); + + updatedRecord = this.getUpdatedRecordIndex(recordData, record.id); + + if (inputValue >= this.recordData().size() - 1) { + recordData[updatedRecord].position = this.getGlobalMaxPosition() + 1; + } else { + recordData[updatedRecord].position = inputValue; + recordData.forEach(function (value, index) { + if (~~value.id !== ~~record.id) { + recordData[index].position = (index !== inputValue) ? index : index + 1; + } + }); + } + + this.reloadGridData(recordData); + + }, + + /** + * Get updated record index + * + * @param recordData + * @param recordId + * @return {number} + */ + getUpdatedRecordIndex: function (recordData, recordId) { + return recordData.map(function (o) { + return ~~o.id + }).indexOf(~~recordId); + }, + + /** + * + * @param recordData to reprocess + */ + reloadGridData: function (recordData) { + this.recordData(recordData.sort(function (a, b) { + return ~~a.position - ~~b.position; + })); + this._updateCollection(); + this.reload(); + }, + + /** + * Event handler for "Send to bottom" button + * + * @param positionObj + * @return {boolean} + */ + sendToBottom: function (positionObj) { + + var objectToUpdate = this.getObjectToUpdate(positionObj), + recordData = this.recordData(), + updatedRecord; + + if (~~this.currentPage() === this.pages) { + objectToUpdate.position = this.maxPosition; + } else { + this.elems([]); + updatedRecord = this.getUpdatedRecordIndex(recordData, objectToUpdate.data().id); + recordData[updatedRecord].position = this.getGlobalMaxPosition() + 1; + this.reloadGridData(recordData); + } + + return false; + }, + + /** + * Event handler for "Send to top" button + * + * @param positionObj + * @returns {boolean} + */ + sendToTop: function (positionObj) { + var objectToUpdate = this.getObjectToUpdate(positionObj), + recordData = this.recordData(), + updatedRecord; + + //isFirst + if (~~this.currentPage() === 1) { + objectToUpdate.position = 0; + } else { + this.elems([]); + updatedRecord = this.getUpdatedRecordIndex(recordData, objectToUpdate.data().id); + recordData.forEach(function (value, index) { + recordData[index].position = (index === updatedRecord) ? 0 : value.position + 1; + }); + this.reloadGridData(recordData); + } + return false; + }, + + /** + * Get element from grid for update + * + * @param object + * @return {*} + */ + getObjectToUpdate: function (object) { + return this.elems().filter(function (item) { + return item.name === object.parentName; + })[0]; + }, + + /** + * Value function for position input + * + * @param data + * @return {number} + */ + getCalculatedPosition: function (data) { + return (~~this.currentPage() - 1) * this.pageSize + this.elems().pluck("name").indexOf(data.name); + }, + + /** + * Returns start index for current page + * + * @return {number} + */ + getStartIndex() { + return (~~this.currentPage() - 1) * this.pageSize; + }, + + /** + * Return Page Boundary + * + * @return {number} + */ + getDefaultPageBoundary: function () { + return (~~this.currentPage() * this.pageSize) - 1; + }, + + /** + * Returns position for last element to be moved after + * + * @return {number} + */ + getGlobalMaxPosition() { + return _.max(this.recordData().map(function (r) { + return ~~r.position + })); + } + + + }); +}); \ No newline at end of file diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html b/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html new file mode 100644 index 0000000000000..dbfeff2e32c04 --- /dev/null +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html @@ -0,0 +1,19 @@ +<div class="position"> + <a href="#" class="move-top icon-backward icon-rearrange-position" + data-bind=" + click: $parent.sendToTop.bind($parent) + "> + <span>Top</span> + </a> + <input type="text" class="position-widget-input" + data-bind=" + value: $parent.getCalculatedPosition($record()), + event: {blur: $parent.updateGridPosition.bind($parent)} + "/> + <a href="#" class="move-bottom icon-forward icon-rearrange-position" + data-bind=" + click: $parent.sendToBottom.bind($parent) + "> + <span>Bottom</span> + </a> +</div> \ No newline at end of file From c5bf8738d26a07a19a477e14aaf79708ba8052fd Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Fri, 28 Sep 2018 16:59:42 +0400 Subject: [PATCH 125/812] MAGETWO-91707: [Sigma Beauty]Cannot pause Youtube video in IE 11 - Add automated test --- .../StorefrontProductInfoMainSection.xml | 4 + .../YoutubeVideoWindowOnProductPageTest.xml | 92 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 app/code/Magento/ProductVideo/Test/Mftf/Test/YoutubeVideoWindowOnProductPageTest.xml diff --git a/app/code/Magento/ProductVideo/Test/Mftf/Section/StorefrontProductInfoMainSection.xml b/app/code/Magento/ProductVideo/Test/Mftf/Section/StorefrontProductInfoMainSection.xml index 564122f71b9f4..c8e1ebcf12d94 100644 --- a/app/code/Magento/ProductVideo/Test/Mftf/Section/StorefrontProductInfoMainSection.xml +++ b/app/code/Magento/ProductVideo/Test/Mftf/Section/StorefrontProductInfoMainSection.xml @@ -10,5 +10,9 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="StorefrontProductInfoMainSection"> <element name="productVideo" type="text" selector="//*[@class='product-video' and @data-type='{{videoType}}']" parameterized="true"/> + <element name="clickInVideo" type="video" selector="//*[@class='fotorama__stage__shaft']"/> + <element name="videoPausedMode" type="video" selector="//*[contains(@class, 'paused-mode')]"/> + <element name="videoPlayedMode" type="video" selector="//*[contains(@class,'playing-mode')]"/> + <element name="frameVideo" type="video" selector="widget2"/> </section> </sections> diff --git a/app/code/Magento/ProductVideo/Test/Mftf/Test/YoutubeVideoWindowOnProductPageTest.xml b/app/code/Magento/ProductVideo/Test/Mftf/Test/YoutubeVideoWindowOnProductPageTest.xml new file mode 100644 index 0000000000000..7249a4223503e --- /dev/null +++ b/app/code/Magento/ProductVideo/Test/Mftf/Test/YoutubeVideoWindowOnProductPageTest.xml @@ -0,0 +1,92 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="YoutubeVideoWindowOnProductPageTest"> + <annotations> + <features value="ProductVideo"/> + <stories value="MAGETWO-91707: [Sigma Beauty]Cannot pause Youtube video in IE 11"/> + <testCaseId value="MAGETWO-95254"/> + <title value="Youtube video window on the product page"/> + <description value="Check Youtube video window on the product page"/> + <severity value="MAJOR"/> + <group value="ProductVideo"/> + </annotations> + + <before> + <!--Log In--> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!--Create category--> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <!--Create product--> + <createData entity="SimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!-- Set product video Youtube api key configuration --> + <createData entity="ProductVideoYoutubeApiKeyConfig" stepKey="setStoreConfig" after="loginAsAdmin"/> + </before> + + <!--Open simple product--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex"/> + <waitForPageLoad stepKey="wait1"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetProductGrid"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterProductGridBySku"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> + <actionGroup ref="openProducForEditByClickingRowXColumnYInProductGrid" stepKey="openFirstProductForEdit"/> + + <!-- Add product video --> + <actionGroup ref="addProductVideo" stepKey="addProductVideo" after="openFirstProductForEdit"/> + <!-- Assert product video in admin product form --> + <actionGroup ref="assertProductVideoAdminProductPage" stepKey="assertProductVideoAdminProductPage" after="addProductVideo"/> + + <!-- Save the product --> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveFirstProduct"/> + <waitForPageLoad stepKey="waitForFirstProductSaved"/> + + <!-- Assert product video in storefront product page --> + <amOnPage url="$$createProduct.name$$.html" stepKey="goToStorefrontCategoryPage"/> + <waitForPageLoad stepKey="waitForStorefrontPageLoaded"/> + <actionGroup ref="assertProductVideoStorefrontProductPage" stepKey="assertProductVideoStorefrontProductPage" after="waitForStorefrontPageLoaded"/> + + <!--Click Play video button--> + <click stepKey="clickToPlayVideo" selector="{{StorefrontProductInfoMainSection.clickInVideo}}"/> + <wait stepKey="waitFiveSecondToPlayVideo" time="5"/> + <switchToIFrame selector="{{StorefrontProductInfoMainSection.frameVideo}}" stepKey="switchToFrame"/> + <waitForElementVisible selector="{{StorefrontProductInfoMainSection.videoPlayedMode}}" stepKey="waitForVideoPlayed"/> + <seeElement selector="{{StorefrontProductInfoMainSection.videoPlayedMode}}" stepKey="AssertVideoIsPlayed"/> + <switchToIFrame stepKey="switchBack1"/> + + <!--Click Pause button--> + <click stepKey="clickToStopVideo" selector="{{StorefrontProductInfoMainSection.clickInVideo}}"/> + <wait stepKey="waitFiveSecondToStopVideo" time="5"/> + <switchToIFrame selector="{{StorefrontProductInfoMainSection.frameVideo}}" stepKey="switchToFrame2"/> + <waitForElementVisible selector="{{StorefrontProductInfoMainSection.videoPausedMode}}" stepKey="waitForVideoPaused"/> + <seeElement selector="{{StorefrontProductInfoMainSection.videoPausedMode}}" stepKey="AssertVideoIsPaused"/> + <switchToIFrame stepKey="switchBack2"/> + + <!--Click Play video button again. Make sure that Video continued playing--> + <click stepKey="clickAgainToPlayVideo" selector="{{StorefrontProductInfoMainSection.clickInVideo}}"/> + <wait stepKey="waitAgainFiveSecondToPlayVideo" time="5"/> + <switchToIFrame selector="{{StorefrontProductInfoMainSection.frameVideo}}" stepKey="switchToFrame3"/> + <waitForElementVisible selector="{{StorefrontProductInfoMainSection.videoPlayedMode}}" stepKey="waitForVideoPlayedAgain"/> + <seeElement selector="{{StorefrontProductInfoMainSection.videoPlayedMode}}" stepKey="AssertVideoIsPlayedAgain"/> + <switchToIFrame stepKey="switchBack3"/> + + <after> + <deleteData createDataKey="createProduct" stepKey="deleteSimpleProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategoryFirst"/> + <!-- Set product video configuration to default --> + <createData entity="DefaultProductVideoConfig" stepKey="setStoreDefaultConfig" before="logout"/> + <!--Log Out--> + <actionGroup ref="logout" stepKey="logout"/> + </after> + </test> +</tests> + From 8f8fc8d9b868e3e73e2267ccca910efa5fa57378 Mon Sep 17 00:00:00 2001 From: Oksana_Kremen <Oksana_Kremen@epam.com> Date: Fri, 28 Sep 2018 17:24:18 +0300 Subject: [PATCH 126/812] MAGETWO-91751: Apostrophe displays as code in the text field box - Skipping to escape single quote --- app/code/Magento/Widget/Model/Widget.php | 6 +++- .../Widget/Test/Unit/Model/WidgetTest.php | 29 ++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Widget/Model/Widget.php b/app/code/Magento/Widget/Model/Widget.php index 085e6ec3b2d77..5ba03d008ded0 100644 --- a/app/code/Magento/Widget/Model/Widget.php +++ b/app/code/Magento/Widget/Model/Widget.php @@ -84,6 +84,8 @@ public function __construct( } /** + * Get math random + * * @return \Magento\Framework\Math\Random * * @deprecated 100.1.0 @@ -315,7 +317,7 @@ public function getWidgetDeclaration($type, $params = [], $asIs = true) } } if (isset($value)) { - $directive .= sprintf(' %s="%s"', $name, $this->escaper->escapeQuote($value)); + $directive .= sprintf(' %s="%s"', $name, $this->escaper->escapeHtmlAttr($value, false)); } } @@ -339,6 +341,8 @@ public function getWidgetDeclaration($type, $params = [], $asIs = true) } /** + * Get widget page varname + * * @param array $params * @return string * @throws \Magento\Framework\Exception\LocalizedException diff --git a/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php b/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php index b85a458ed4121..5c546d7e2435c 100644 --- a/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php +++ b/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php @@ -32,6 +32,9 @@ class WidgetTest extends \PHPUnit\Framework\TestCase */ private $conditionsHelper; + /** + * @inheritdoc + */ protected function setUp() { $this->dataStorageMock = $this->getMockBuilder(\Magento\Widget\Model\Config\Data::class) @@ -55,6 +58,9 @@ protected function setUp() ); } + /** + * Unit test for getWidget + */ public function testGetWidgets() { $expected = ['val1', 'val2']; @@ -65,6 +71,9 @@ public function testGetWidgets() $this->assertEquals($expected, $result); } + /** + * Unit test for getWidgetsWithFilter + */ public function testGetWidgetsWithFilter() { $configFile = __DIR__ . '/_files/mappedConfigArrayAll.php'; @@ -78,6 +87,9 @@ public function testGetWidgetsWithFilter() $this->assertEquals($expected, $result); } + /** + * Unit test for getWidgetsWithUnknownFilter + */ public function testGetWidgetsWithUnknownFilter() { $configFile = __DIR__ . '/_files/mappedConfigArrayAll.php'; @@ -90,6 +102,9 @@ public function testGetWidgetsWithUnknownFilter() $this->assertEquals($expected, $result); } + /** + * Unit test for getWidgetByClassType + */ public function testGetWidgetByClassType() { $widgetOne = ['@' => ['type' => 'type1']]; @@ -101,6 +116,9 @@ public function testGetWidgetByClassType() $this->assertNull($this->widget->getWidgetByClassType('type2')); } + /** + * Unit test for getConfigAsObject + */ public function testGetConfigAsObject() { $configFile = __DIR__ . '/_files/mappedConfigArrayAll.php'; @@ -135,6 +153,9 @@ public function testGetConfigAsObject() $this->assertSame($supportedContainersExpected, $resultObject->getSupportedContainers()); } + /** + * Unit test for getConfigAsObjectWidgetNoFound + */ public function testGetConfigAsObjectWidgetNoFound() { $this->dataStorageMock->expects($this->once()) @@ -146,6 +167,9 @@ public function testGetConfigAsObjectWidgetNoFound() $this->assertSame([], $resultObject->getData()); } + /** + * Unit test for getWidgetDeclaration + */ public function testGetWidgetDeclaration() { $mathRandomMock = $this->createPartialMock(\Magento\Framework\Math\Random::class, ['getRandomString']); @@ -175,7 +199,7 @@ public function testGetWidgetDeclaration() $this->conditionsHelper->expects($this->once())->method('encode')->with($conditions) ->willReturn('encoded-conditions-string'); $this->escaperMock->expects($this->atLeastOnce()) - ->method('escapeQuote') + ->method('escapeHtmlAttr') ->willReturnMap([ ['my "widget"', false, 'my "widget"'], ['1', false, '1'], @@ -203,6 +227,9 @@ public function testGetWidgetDeclaration() $this->assertContains('type_name=""}}', $result); } + /** + * Unit test for getWidgetDeclarationWithZeroValueParam + */ public function testGetWidgetDeclarationWithZeroValueParam() { $mathRandomMock = $this->createPartialMock(\Magento\Framework\Math\Random::class, ['getRandomString']); From b82bec83167297f80529b9af0e2045fc55ec6b74 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <kopylova@adobe.com> Date: Fri, 28 Sep 2018 13:51:17 -0500 Subject: [PATCH 127/812] MAGETWO-95259: CatalogSearch module deprecation must be reverted - removed deprecation from generic catalog search classes --- app/code/Magento/CatalogSearch/Block/Advanced/Form.php | 2 -- .../CatalogSearch/Block/Plugin/FrontTabPlugin.php | 4 +--- app/code/Magento/CatalogSearch/Block/Result.php | 2 -- app/code/Magento/CatalogSearch/Block/SearchTermsLog.php | 4 +--- .../Magento/CatalogSearch/Controller/Advanced/Index.php | 4 ---- .../Magento/CatalogSearch/Controller/Advanced/Result.php | 4 ---- .../Magento/CatalogSearch/Controller/Result/Index.php | 4 ---- .../CatalogSearch/Controller/SearchTermsLog/Save.php | 2 -- app/code/Magento/CatalogSearch/Helper/Data.php | 2 -- .../Adapter/Aggregation/Checker/Query/AdvancedSearch.php | 2 -- app/code/Magento/CatalogSearch/Model/Adapter/Options.php | 2 -- .../Model/Adminhtml/System/Config/Backend/Engine.php | 2 -- .../CatalogSearch/Model/Attribute/SearchWeight.php | 3 --- .../CatalogSearch/Model/Autocomplete/DataProvider.php | 4 ---- .../Magento/CatalogSearch/Model/Indexer/Fulltext.php | 2 -- .../Model/Indexer/Fulltext/Action/DataProvider.php | 2 -- .../Model/Indexer/Fulltext/Model/Plugin/Category.php | 3 --- .../Model/Indexer/Fulltext/Plugin/AbstractPlugin.php | 3 --- .../Model/Indexer/Fulltext/Plugin/Attribute.php | 4 ---- .../Model/Indexer/Fulltext/Plugin/Category.php | 4 ---- .../Model/Indexer/Fulltext/Plugin/Product.php | 4 ---- .../Model/Indexer/Fulltext/Plugin/Store/Group.php | 3 --- .../Model/Indexer/Fulltext/Plugin/Store/View.php | 3 --- .../CatalogSearch/Model/Indexer/Fulltext/Processor.php | 2 -- .../CatalogSearch/Model/Indexer/Fulltext/Store.php | 4 ---- .../Model/Indexer/IndexStructureFactory.php | 2 -- .../Model/Indexer/IndexerHandlerFactory.php | 2 -- .../Magento/CatalogSearch/Model/Indexer/Mview/Action.php | 4 ---- .../Model/Layer/Category/ItemCollectionProvider.php | 4 ---- .../CatalogSearch/Model/Layer/Filter/Attribute.php | 2 -- .../CatalogSearch/Model/Layer/Filter/Category.php | 3 --- .../Magento/CatalogSearch/Model/Layer/Filter/Decimal.php | 3 --- .../Magento/CatalogSearch/Model/Layer/Filter/Price.php | 2 -- .../Model/Layer/Search/Plugin/CollectionFilter.php | 4 ---- .../CatalogSearch/Model/Layer/Search/StateKey.php | 4 ---- app/code/Magento/CatalogSearch/Model/Price/Interval.php | 4 ---- .../Model/ResourceModel/EngineInterface.php | 7 +------ .../CatalogSearch/Model/ResourceModel/EngineProvider.php | 9 ++------- .../BaseSelectStrategy/BaseSelectStrategyInterface.php | 1 - .../Model/Search/BaseSelectStrategy/StrategyMapper.php | 1 - app/code/Magento/CatalogSearch/Model/Search/Catalog.php | 3 --- .../Model/Search/CustomAttributeFilterCheck.php | 1 - .../Model/Search/SelectContainer/SelectContainer.php | 1 - app/code/Magento/CatalogSearch/Model/Source/Weight.php | 2 -- .../Magento/CatalogSearch/Plugin/EnableEavIndexer.php | 3 +++ app/code/Magento/Search/Model/Query.php | 1 - 46 files changed, 8 insertions(+), 130 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Block/Advanced/Form.php b/app/code/Magento/CatalogSearch/Block/Advanced/Form.php index 863165ecf720d..4d1957991d1bf 100644 --- a/app/code/Magento/CatalogSearch/Block/Advanced/Form.php +++ b/app/code/Magento/CatalogSearch/Block/Advanced/Form.php @@ -23,8 +23,6 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Form extends Template { diff --git a/app/code/Magento/CatalogSearch/Block/Plugin/FrontTabPlugin.php b/app/code/Magento/CatalogSearch/Block/Plugin/FrontTabPlugin.php index be65372725ceb..85ad66013cf32 100644 --- a/app/code/Magento/CatalogSearch/Block/Plugin/FrontTabPlugin.php +++ b/app/code/Magento/CatalogSearch/Block/Plugin/FrontTabPlugin.php @@ -11,9 +11,7 @@ use Magento\Framework\Data\Form\Element\Fieldset; /** - * Plugin for Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Front - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * Add Search Weight field to the product attribute add/edit tab */ class FrontTabPlugin { diff --git a/app/code/Magento/CatalogSearch/Block/Result.php b/app/code/Magento/CatalogSearch/Block/Result.php index ccc8950450dad..f0d899b678c78 100644 --- a/app/code/Magento/CatalogSearch/Block/Result.php +++ b/app/code/Magento/CatalogSearch/Block/Result.php @@ -18,8 +18,6 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Result extends Template { diff --git a/app/code/Magento/CatalogSearch/Block/SearchTermsLog.php b/app/code/Magento/CatalogSearch/Block/SearchTermsLog.php index 3679803c04d02..005c7860cfe5f 100644 --- a/app/code/Magento/CatalogSearch/Block/SearchTermsLog.php +++ b/app/code/Magento/CatalogSearch/Block/SearchTermsLog.php @@ -9,9 +9,7 @@ use Magento\Framework\View\Element\Block\ArgumentInterface; /** - * Class for logging search terms on cached pages - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * Provider of the information on whether the page is cacheable, so that AJAX-based logging of terms can be triggered */ class SearchTermsLog implements ArgumentInterface { diff --git a/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php b/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php index a669016eb6b1b..bc60a5c9b106c 100644 --- a/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php +++ b/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php @@ -10,10 +10,6 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Index extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface, HttpPostActionInterface { /** diff --git a/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php b/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php index 937175511b1fb..145db146347bc 100644 --- a/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php +++ b/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php @@ -12,10 +12,6 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\UrlFactory; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Result extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface, HttpPostActionInterface { /** diff --git a/app/code/Magento/CatalogSearch/Controller/Result/Index.php b/app/code/Magento/CatalogSearch/Controller/Result/Index.php index 7c3577df452e4..df00e4c7106ba 100644 --- a/app/code/Magento/CatalogSearch/Controller/Result/Index.php +++ b/app/code/Magento/CatalogSearch/Controller/Result/Index.php @@ -15,10 +15,6 @@ use Magento\Search\Model\QueryFactory; use Magento\Search\Model\PopularSearchTerms; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Index extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface, HttpPostActionInterface { /** diff --git a/app/code/Magento/CatalogSearch/Controller/SearchTermsLog/Save.php b/app/code/Magento/CatalogSearch/Controller/SearchTermsLog/Save.php index f4018ed5b5d0d..a4a843c636cd0 100644 --- a/app/code/Magento/CatalogSearch/Controller/SearchTermsLog/Save.php +++ b/app/code/Magento/CatalogSearch/Controller/SearchTermsLog/Save.php @@ -15,8 +15,6 @@ /** * Controller for save search terms - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Save extends \Magento\Framework\App\Action\Action { diff --git a/app/code/Magento/CatalogSearch/Helper/Data.php b/app/code/Magento/CatalogSearch/Helper/Data.php index 7ba438ff36a58..6898e33d49f1d 100644 --- a/app/code/Magento/CatalogSearch/Helper/Data.php +++ b/app/code/Magento/CatalogSearch/Helper/Data.php @@ -10,8 +10,6 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Data extends \Magento\Search\Helper\Data { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php index bb0de00816337..8f1f3fde14240 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php @@ -12,8 +12,6 @@ * Request checker for advanced search. * * Checks advanced search query whether required to collect all attributes for entity. - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class AdvancedSearch implements RequestCheckerInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Options.php b/app/code/Magento/CatalogSearch/Model/Adapter/Options.php index efc955486708c..425e6c0041616 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Options.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Options.php @@ -12,8 +12,6 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Options implements OptionsInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php b/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php index 5262316e2ca38..5447ff635f992 100644 --- a/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php +++ b/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php @@ -8,8 +8,6 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Engine extends \Magento\Framework\App\Config\Value { diff --git a/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php b/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php index 139154be9df3a..d6110f4b3b2c9 100644 --- a/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php +++ b/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php @@ -11,9 +11,6 @@ * which is used to boost matches by specific attributes. * * This is part of search accuracy customization functionality. - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class SearchWeight { diff --git a/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php index 82a64923ef702..c1c9997bc83ea 100644 --- a/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php @@ -13,10 +13,6 @@ use Magento\Framework\App\Config\ScopeConfigInterface as ScopeConfig; use Magento\Store\Model\ScopeInterface; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class DataProvider implements DataProviderInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php index ee66a91f395b9..21d8b7297da7d 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php @@ -19,8 +19,6 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Fulltext implements \Magento\Framework\Indexer\ActionInterface, 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 83058b6f0ad55..a8d46911193a8 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -16,8 +16,6 @@ * @SuppressWarnings(PHPMD.TooManyFields) * @api * @since 100.0.3 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class DataProvider { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Model/Plugin/Category.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Model/Plugin/Category.php index eee6ac37767ee..ed841996ea07b 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Model/Plugin/Category.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Model/Plugin/Category.php @@ -12,9 +12,6 @@ /** * Perform indexer invalidation after a category delete. - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Category { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/AbstractPlugin.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/AbstractPlugin.php index 61b7075043d29..5d4096a3afab0 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/AbstractPlugin.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/AbstractPlugin.php @@ -10,9 +10,6 @@ /** * Abstract plugin for indexers - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ abstract class AbstractPlugin { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php index ae218f65087d4..83ad7acca84dc 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php @@ -7,10 +7,6 @@ use Magento\CatalogSearch\Model\Indexer\Fulltext; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Attribute extends AbstractPlugin { /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php index 0cf9f04f97613..ca701db7d2a93 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php @@ -9,10 +9,6 @@ use Magento\Catalog\Model\ResourceModel\Category as ResourceCategory; use Magento\Framework\Model\AbstractModel; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Category extends AbstractPlugin { /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php index 120a22f60d048..c8dbd89017b7c 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php @@ -9,10 +9,6 @@ use Magento\Catalog\Model\ResourceModel\Product as ResourceProduct; use Magento\Framework\Model\AbstractModel; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Product extends AbstractPlugin { /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/Group.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/Group.php index 27a2bd82a5d7e..73a79f7c87239 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/Group.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/Group.php @@ -12,9 +12,6 @@ /** * Plugin for Magento\Store\Model\ResourceModel\Group - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Group extends AbstractIndexerPlugin { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/View.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/View.php index 51695fd261d7b..7f0c5fdae6d42 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/View.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Store/View.php @@ -12,9 +12,6 @@ /** * Plugin for Magento\Store\Model\ResourceModel\Store - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class View extends AbstractIndexerPlugin { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Processor.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Processor.php index 33881061eb88d..cd3ff62d53682 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Processor.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Processor.php @@ -12,8 +12,6 @@ * Class Processor * @api * @since 100.1.0 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Processor extends AbstractProcessor { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php index 8b0a18105ec84..e971f59cf10f2 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php @@ -11,10 +11,6 @@ use Magento\Framework\Indexer\ConfigInterface; use Magento\Framework\Event\ObserverInterface; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Store implements ObserverInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php index 4bdd4336c5257..d8b3c19ddb918 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php @@ -12,8 +12,6 @@ /** * @api * @since 100.1.0 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class IndexStructureFactory { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php index af1839f04ab38..b9b44df6f404f 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php @@ -12,8 +12,6 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class IndexerHandlerFactory { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php b/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php index ba5a16978c59b..47a8681a73c60 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php @@ -9,10 +9,6 @@ use Magento\Framework\Mview\ActionInterface; use Magento\Framework\Indexer\IndexerInterfaceFactory; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Action implements ActionInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php b/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php index 02beeae0f1579..4ce286bf15922 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php @@ -9,10 +9,6 @@ use Magento\Catalog\Model\Layer\ItemCollectionProviderInterface; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class ItemCollectionProvider implements ItemCollectionProviderInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php index 8119d7c5869c5..7aac6e98fc044 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php @@ -9,8 +9,6 @@ /** * Layer attribute filter - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Attribute extends AbstractFilter { diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php index 63d9656fea25a..7c15514f211d2 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php @@ -10,9 +10,6 @@ /** * Layer category filter - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Category extends AbstractFilter { diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Decimal.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Decimal.php index a3b1d76fef151..e61a886a41d6f 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Decimal.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Decimal.php @@ -9,9 +9,6 @@ /** * Layer decimal filter - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Decimal extends AbstractFilter { diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php index 126a0a7ea3212..108f1b9f4fd8d 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php @@ -10,8 +10,6 @@ /** * Layer price filter based on Search API * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Price extends AbstractFilter diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php b/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php index 5fbd08c134334..4ffd8ff4ba5ea 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php @@ -9,10 +9,6 @@ use Magento\Catalog\Model\Category; use Magento\Search\Model\QueryFactory; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class CollectionFilter { /** diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php b/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php index 16a22aba8db35..4f14b7daba1d5 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php @@ -9,10 +9,6 @@ use Magento\Catalog\Model\Layer\StateKeyInterface; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class StateKey extends \Magento\Catalog\Model\Layer\Category\StateKey implements StateKeyInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Price/Interval.php b/app/code/Magento/CatalogSearch/Model/Price/Interval.php index 69e4b90baf04d..db1d550c3724b 100644 --- a/app/code/Magento/CatalogSearch/Model/Price/Interval.php +++ b/app/code/Magento/CatalogSearch/Model/Price/Interval.php @@ -7,10 +7,6 @@ use Magento\Framework\Search\Dynamic\IntervalInterface; -/** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ class Interval implements IntervalInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineInterface.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineInterface.php index 99d34de1830b7..4b9db55105ea9 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineInterface.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineInterface.php @@ -3,16 +3,11 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +namespace Magento\CatalogSearch\Model\ResourceModel; /** * CatalogSearch Index Engine Interface * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ -namespace Magento\CatalogSearch\Model\ResourceModel; - -/** * @api * @since 100.0.2 */ diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineProvider.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineProvider.php index 6faffefde6095..d1259159606d3 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineProvider.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/EngineProvider.php @@ -4,18 +4,13 @@ * See COPYING.txt for license details. */ -/** - * Catalog Search engine provider - * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. - */ namespace Magento\CatalogSearch\Model\ResourceModel; -use Magento\CatalogSearch\Model\ResourceModel\EngineInterface; use Magento\Framework\Search\EngineResolverInterface; /** + * Catalog Search engine provider + * * @api * @since 100.0.2 */ diff --git a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php index 32ecb49714246..1904df9ccd53b 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php @@ -8,7 +8,6 @@ use Magento\CatalogSearch\Model\Search\SelectContainer\SelectContainer; /** - * Interface BaseSelectStrategyInterface * This interface represents strategy that will be used to create base select for search request * * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} diff --git a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php index 9e954b57f649f..963dd53295430 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php +++ b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php @@ -10,7 +10,6 @@ use Magento\CatalogSearch\Model\Adapter\Mysql\BaseSelectStrategy\BaseSelectAttributesSearchStrategy; /** - * Class StrategyMapper * This class is responsible for deciding which BaseSelectStrategyInterface should be used for passed SelectContainer * * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} diff --git a/app/code/Magento/CatalogSearch/Model/Search/Catalog.php b/app/code/Magento/CatalogSearch/Model/Search/Catalog.php index 7a39a7bf47824..31ac889b19e69 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/Catalog.php +++ b/app/code/Magento/CatalogSearch/Model/Search/Catalog.php @@ -9,9 +9,6 @@ /** * Search model for backend search - * - * @deprecated 100.2.0 - * @see ElasticSearch module is default search engine starting from 2.3. CatalogSearch would be removed in 2.4 */ class Catalog extends \Magento\Framework\DataObject { diff --git a/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php b/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php index ce8ce6829a008..bac8c1bb57c11 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php +++ b/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php @@ -10,7 +10,6 @@ use Magento\Catalog\Model\Product; /** - * Class CustomAttributeFilterSelector * Checks if FilterInterface is by custom attribute * * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} diff --git a/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php b/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php index ffd434251f9f5..e32785a6a17af 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php +++ b/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php @@ -10,7 +10,6 @@ use Magento\Framework\Search\Request\FilterInterface; /** - * Class SelectContainer * This class is a container for all data that is required for creating select query by search request * * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} diff --git a/app/code/Magento/CatalogSearch/Model/Source/Weight.php b/app/code/Magento/CatalogSearch/Model/Source/Weight.php index c02d861fda8dd..495e1a4567d63 100644 --- a/app/code/Magento/CatalogSearch/Model/Source/Weight.php +++ b/app/code/Magento/CatalogSearch/Model/Source/Weight.php @@ -9,8 +9,6 @@ * Attribute weight options * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. */ class Weight implements \Magento\Framework\Data\OptionSourceInterface { diff --git a/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php b/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php index c624f9d1c2e52..cb7210813b056 100644 --- a/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php +++ b/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php @@ -9,6 +9,9 @@ /** * Enable Product EAV indexer in configuration for MySQL search engine + * + * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} + * will replace it as the default search engine. */ class EnableEavIndexer { diff --git a/app/code/Magento/Search/Model/Query.php b/app/code/Magento/Search/Model/Query.php index 365e03b3648a7..b104fd0329795 100644 --- a/app/code/Magento/Search/Model/Query.php +++ b/app/code/Magento/Search/Model/Query.php @@ -5,7 +5,6 @@ */ namespace Magento\Search\Model; -use Magento\Framework\App\ResourceConnection; use Magento\Search\Model\ResourceModel\Query\Collection as QueryCollection; use Magento\Search\Model\ResourceModel\Query\CollectionFactory as QueryCollectionFactory; use Magento\Search\Model\SearchCollectionInterface as Collection; From 19679902520463442d54d8c03a984ae7718c04d3 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <kopylova@adobe.com> Date: Fri, 28 Sep 2018 14:05:20 -0500 Subject: [PATCH 128/812] MAGETWO-95259: CatalogSearch module deprecation must be reverted - updated message --- app/code/Magento/CatalogSearch/Block/Advanced/Result.php | 4 ++-- .../Model/Adapter/Aggregation/AggregationResolver.php | 4 ++-- .../Model/Adapter/Aggregation/Checker/Query/CatalogView.php | 4 ++-- .../Model/Adapter/Aggregation/RequestCheckerComposite.php | 4 ++-- .../Model/Adapter/Aggregation/RequestCheckerInterface.php | 4 ++-- .../Model/Adapter/Mysql/Aggregation/DataProvider.php | 4 ++-- .../Adapter/Mysql/Aggregation/DataProvider/QueryBuilder.php | 4 ++-- .../Aggregation/DataProvider/SelectBuilderForAttribute.php | 4 ++-- .../SelectBuilderForAttribute/ApplyStockConditionToSelect.php | 4 ++-- .../BaseSelectStrategy/BaseSelectAttributesSearchStrategy.php | 4 ++-- .../BaseSelectStrategy/BaseSelectFullTextSearchStrategy.php | 4 ++-- .../Model/Adapter/Mysql/Dynamic/DataProvider.php | 4 ++-- .../CatalogSearch/Model/Adapter/Mysql/Field/Resolver.php | 4 ++-- .../Model/Adapter/Mysql/Filter/AliasResolver.php | 4 ++-- .../CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php | 4 ++-- .../Mysql/Plugin/Aggregation/Category/DataProvider.php | 4 ++-- app/code/Magento/CatalogSearch/Model/Advanced.php | 4 ++-- .../Magento/CatalogSearch/Model/Advanced/Request/Builder.php | 4 ++-- app/code/Magento/CatalogSearch/Model/Fulltext.php | 4 ++-- .../CatalogSearch/Model/Indexer/Fulltext/Action/Full.php | 4 ++-- .../Model/Indexer/Fulltext/Action/IndexIterator.php | 4 ++-- .../Magento/CatalogSearch/Model/Indexer/IndexStructure.php | 4 ++-- .../CatalogSearch/Model/Indexer/IndexStructureProxy.php | 4 ++-- .../CatalogSearch/Model/Indexer/IndexSwitcherInterface.php | 4 ++-- .../CatalogSearch/Model/Indexer/IndexSwitcherProxy.php | 4 ++-- .../Magento/CatalogSearch/Model/Indexer/IndexerHandler.php | 4 ++-- .../Magento/CatalogSearch/Model/Indexer/ProductFieldset.php | 4 ++-- .../CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php | 4 ++-- .../Model/Indexer/Scope/IndexTableNotExistException.php | 4 ++-- .../Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php | 4 ++-- app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php | 4 ++-- .../CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php | 4 ++-- .../Model/Indexer/Scope/UnknownStateException.php | 4 ++-- .../Magento/CatalogSearch/Model/ResourceModel/Advanced.php | 4 ++-- .../CatalogSearch/Model/ResourceModel/Advanced/Collection.php | 4 ++-- app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php | 4 ++-- .../Magento/CatalogSearch/Model/ResourceModel/Fulltext.php | 4 ++-- .../CatalogSearch/Model/ResourceModel/Fulltext/Collection.php | 4 ++-- .../CatalogSearch/Model/ResourceModel/Search/Collection.php | 4 ++-- .../Search/BaseSelectStrategy/BaseSelectStrategyInterface.php | 4 ++-- .../Model/Search/BaseSelectStrategy/StrategyMapper.php | 4 ++-- .../CatalogSearch/Model/Search/CustomAttributeFilterCheck.php | 4 ++-- .../Model/Search/FilterMapper/CustomAttributeFilter.php | 4 ++-- .../Model/Search/FilterMapper/DimensionsProcessor.php | 4 ++-- .../Model/Search/FilterMapper/ExclusionStrategy.php | 4 ++-- .../CatalogSearch/Model/Search/FilterMapper/FilterContext.php | 4 ++-- .../CatalogSearch/Model/Search/FilterMapper/FilterMapper.php | 4 ++-- .../Model/Search/FilterMapper/FilterStrategyInterface.php | 4 ++-- .../Model/Search/FilterMapper/StaticAttributeStrategy.php | 4 ++-- .../Model/Search/FilterMapper/StockStatusFilter.php | 4 ++-- .../Model/Search/FilterMapper/TermDropdownStrategy.php | 4 ++-- .../TermDropdownStrategy/ApplyStockConditionToSelect.php | 4 ++-- .../FilterMapper/TermDropdownStrategy/SelectBuilder.php | 4 ++-- .../Model/Search/FilterMapper/VisibilityFilter.php | 4 ++-- .../Magento/CatalogSearch/Model/Search/FiltersExtractor.php | 4 ++-- app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php | 4 ++-- .../Model/Search/QueryChecker/FullTextSearchCheck.php | 4 ++-- app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php | 4 ++-- .../Magento/CatalogSearch/Model/Search/RequestGenerator.php | 4 ++-- .../CatalogSearch/Model/Search/RequestGenerator/Decimal.php | 4 ++-- .../CatalogSearch/Model/Search/RequestGenerator/General.php | 4 ++-- .../Model/Search/RequestGenerator/GeneratorInterface.php | 4 ++-- .../Model/Search/RequestGenerator/GeneratorResolver.php | 4 ++-- .../Model/Search/SelectContainer/SelectContainer.php | 4 ++-- .../Model/Search/SelectContainer/SelectContainerBuilder.php | 4 ++-- app/code/Magento/CatalogSearch/Model/Search/TableMapper.php | 4 ++-- app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php | 4 ++-- .../Setup/Patch/Data/SetInitialSearchWeightForAttributes.php | 4 ++-- app/code/Magento/CatalogSearch/composer.json | 2 +- 69 files changed, 137 insertions(+), 137 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php index 65bc7b5fb0c20..79f6024132be7 100644 --- a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php +++ b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php @@ -18,8 +18,8 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Result extends Template { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php index 2e41183940052..639c0aecb3615 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php @@ -15,8 +15,8 @@ use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection as AttributeCollection; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class AggregationResolver implements AggregationResolverInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php index 3990587fa8c75..1ac7ad3773740 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php @@ -17,8 +17,8 @@ * Request checker for catalog view. * * Checks catalog view query whether required to collect all attributes for entity. - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class CatalogView implements RequestCheckerInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php index 70c076fc21639..7e0ad7c46d6f3 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php @@ -10,8 +10,8 @@ use Magento\Store\Model\StoreManagerInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class RequestCheckerComposite implements RequestCheckerInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php index 5c28db9a3b07a..81b7414380bf1 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php @@ -10,8 +10,8 @@ /** * RequestCheckerInterface provides the interface to work with query checkers. * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ interface RequestCheckerInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php index 48a78204774f7..15856bbee7461 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php @@ -18,8 +18,8 @@ use Magento\Framework\Search\Request\BucketInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class DataProvider implements DataProviderInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilder.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilder.php index 29238022811c5..26837448f2df2 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilder.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilder.php @@ -22,8 +22,8 @@ /** * Attribute query builder * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute.php index 155dea824cde2..ddb4085fa13d9 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute.php @@ -22,8 +22,8 @@ /** * Build select for attribute. * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class SelectBuilderForAttribute { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute/ApplyStockConditionToSelect.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute/ApplyStockConditionToSelect.php index aa3d82954cfe7..be572793f1ec3 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute/ApplyStockConditionToSelect.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider/SelectBuilderForAttribute/ApplyStockConditionToSelect.php @@ -14,8 +14,8 @@ /** * Join stock table with stock condition to select. * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class ApplyStockConditionToSelect { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectAttributesSearchStrategy.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectAttributesSearchStrategy.php index 8ee404e9df2ba..27a784f8609bb 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectAttributesSearchStrategy.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectAttributesSearchStrategy.php @@ -19,8 +19,8 @@ * The main idea of this strategy is using eav index table as main table for query * in case when search request requires search by attributes * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class BaseSelectAttributesSearchStrategy implements BaseSelectStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectFullTextSearchStrategy.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectFullTextSearchStrategy.php index b0bf91013af35..bff878122c8c4 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectFullTextSearchStrategy.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/BaseSelectStrategy/BaseSelectFullTextSearchStrategy.php @@ -18,8 +18,8 @@ * The main idea of this strategy is using fulltext search index table as main table for query * in case when search request does not requires any search by attributes * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class BaseSelectFullTextSearchStrategy implements BaseSelectStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Dynamic/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Dynamic/DataProvider.php index bed27c16f3ab8..eb4761adf830c 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Dynamic/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Dynamic/DataProvider.php @@ -24,8 +24,8 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class DataProvider implements DataProviderInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Field/Resolver.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Field/Resolver.php index 30be62826fc9a..c24acf4610e07 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Field/Resolver.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Field/Resolver.php @@ -11,8 +11,8 @@ use Magento\Framework\Search\Adapter\Mysql\Field\ResolverInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Resolver implements ResolverInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php index 82bd3d139f35d..bf431396cc0c7 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php @@ -12,8 +12,8 @@ * Purpose of class is to resolve table alias for Search Request filter * @api * @since 100.1.6 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class AliasResolver { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php index c51de6e28b26d..2ffa63098cdee 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php @@ -25,8 +25,8 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Preprocessor implements PreprocessorInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php index 6bf5bb632f02b..a5650cac73395 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php @@ -18,8 +18,8 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class DataProvider { diff --git a/app/code/Magento/CatalogSearch/Model/Advanced.php b/app/code/Magento/CatalogSearch/Model/Advanced.php index 81c0ecdb32128..b49809cfc8059 100644 --- a/app/code/Magento/CatalogSearch/Model/Advanced.php +++ b/app/code/Magento/CatalogSearch/Model/Advanced.php @@ -43,8 +43,8 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Advanced extends \Magento\Framework\Model\AbstractModel { diff --git a/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php b/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php index 4584838782a98..be2609ccc338a 100644 --- a/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php +++ b/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php @@ -10,8 +10,8 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Builder extends RequestBuilder { diff --git a/app/code/Magento/CatalogSearch/Model/Fulltext.php b/app/code/Magento/CatalogSearch/Model/Fulltext.php index 2e7eb097af5cf..398d6e9dd18dd 100644 --- a/app/code/Magento/CatalogSearch/Model/Fulltext.php +++ b/app/code/Magento/CatalogSearch/Model/Fulltext.php @@ -22,8 +22,8 @@ * @method string getDataIndex() * @method \Magento\CatalogSearch\Model\Fulltext setDataIndex(string $value) * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Fulltext extends \Magento\Framework\Model\AbstractModel { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php index 2b4be8369de59..9ea4007c6bde1 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php @@ -23,8 +23,8 @@ * @api * @since 100.0.2 * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Full { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/IndexIterator.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/IndexIterator.php index 1a18b4c05e396..a2c39deff1892 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/IndexIterator.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/IndexIterator.php @@ -15,8 +15,8 @@ * @api * @since 100.0.3 * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexIterator implements \Iterator { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php index 31916c456f000..0308fda657375 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php @@ -17,8 +17,8 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexStructure implements IndexStructureInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php index cee6bb9f6488e..f8863aca8db9c 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php @@ -8,8 +8,8 @@ use Magento\Framework\Indexer\IndexStructureInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexStructureProxy implements IndexStructureInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php index 798801187b4e4..1cdd9c5b9fa5e 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php @@ -9,8 +9,8 @@ * Provides a functionality to replace main index with its temporary representation * @api * @since 100.2.0 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ interface IndexSwitcherInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php index f3b6399c4d7e2..cd0aa12f9137b 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php @@ -12,8 +12,8 @@ /** * Proxy for adapter-specific index switcher * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexSwitcherProxy implements IndexSwitcherInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php index bbdb1dd7b6502..9f105bd3ea462 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php @@ -18,8 +18,8 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexerHandler implements IndexerInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/ProductFieldset.php b/app/code/Magento/CatalogSearch/Model/Indexer/ProductFieldset.php index 426fa69a5fd09..6db063bde7d1e 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/ProductFieldset.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/ProductFieldset.php @@ -13,8 +13,8 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class ProductFieldset implements \Magento\Framework\Indexer\FieldsetInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php index 168446e960689..ed2b1be5c7035 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php @@ -12,8 +12,8 @@ /** * Provides a functionality to replace main index with its temporary representation * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexSwitcher implements IndexSwitcherInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexTableNotExistException.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexTableNotExistException.php index fa7bcce8f2274..b01f3c50d5002 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexTableNotExistException.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexTableNotExistException.php @@ -14,8 +14,8 @@ * * @api * @since 100.2.0 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexTableNotExistException extends LocalizedException { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php index c96ccf3663b48..02d533d7bcb49 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php @@ -12,8 +12,8 @@ * Implementation of IndexScopeResolverInterface which resolves index scope dynamically * depending on current scope state * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class ScopeProxy implements \Magento\Framework\Search\Request\IndexScopeResolverInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php index f11d8709ba4a3..35f616f109638 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php @@ -19,8 +19,8 @@ * which means that default indexer table should be left unchanged during indexation * and temporary table should be used instead. * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class State { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php index 70af9cafd749e..796559d1f7034 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php @@ -12,8 +12,8 @@ /** * Resolves name of a temporary table for indexation * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class TemporaryResolver implements \Magento\Framework\Search\Request\IndexScopeResolverInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/UnknownStateException.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/UnknownStateException.php index cce195c953ebd..8722cd52b618a 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/UnknownStateException.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/UnknownStateException.php @@ -13,8 +13,8 @@ * * @api * @since 100.2.0 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class UnknownStateException extends LocalizedException { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php index 2aab76cb9536f..d88e5627df0e0 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php @@ -11,8 +11,8 @@ * @author Magento Core Team <core@magentocommerce.com> * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Advanced extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php index 8d097487b1bfe..a660cf62b1ad9 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php @@ -23,8 +23,8 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php index a6a97a89882a2..49caede8c4ac2 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php @@ -8,8 +8,8 @@ /** * CatalogSearch Fulltext Index Engine resource model * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Engine implements EngineInterface { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php index 49d1fe82d8e28..ff9aeb4fb4474 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php @@ -14,8 +14,8 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Fulltext extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index 7e0cb306d483b..916bfdd602029 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -24,8 +24,8 @@ * * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php index e706756515a14..aff558c6d0244 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php @@ -12,8 +12,8 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection implements \Magento\Search\Model\SearchCollectionInterface diff --git a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php index 1904df9ccd53b..2d8dfb9222497 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/BaseSelectStrategyInterface.php @@ -10,8 +10,8 @@ /** * This interface represents strategy that will be used to create base select for search request * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ interface BaseSelectStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php index 963dd53295430..e554d3c774a31 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php +++ b/app/code/Magento/CatalogSearch/Model/Search/BaseSelectStrategy/StrategyMapper.php @@ -12,8 +12,8 @@ /** * This class is responsible for deciding which BaseSelectStrategyInterface should be used for passed SelectContainer * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class StrategyMapper { diff --git a/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php b/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php index bac8c1bb57c11..bcd4080b30b14 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php +++ b/app/code/Magento/CatalogSearch/Model/Search/CustomAttributeFilterCheck.php @@ -12,8 +12,8 @@ /** * Checks if FilterInterface is by custom attribute * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class CustomAttributeFilterCheck { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php index 4431d3d7dab58..a8bb3b2fe281f 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/CustomAttributeFilter.php @@ -19,8 +19,8 @@ * Class CustomAttributeFilter * Applies filters by custom attributes to base select * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class CustomAttributeFilter { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/DimensionsProcessor.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/DimensionsProcessor.php index df314377b5afc..3d2b9eed03761 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/DimensionsProcessor.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/DimensionsProcessor.php @@ -17,8 +17,8 @@ * Class DimensionsProcessor * Adds dimension conditions to select query * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class DimensionsProcessor { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php index e7cf5da09351d..c382569338e29 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php @@ -21,8 +21,8 @@ /** * Strategy which processes exclusions from general rules * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php index 692e199fffa01..67ed66da2a036 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php @@ -15,8 +15,8 @@ * Its responsibility is to choose appropriate strategy to apply passed filter to the Select * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class FilterContext implements FilterStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterMapper.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterMapper.php index 49a55ddf26e4b..7136fad5b19a9 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterMapper.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterMapper.php @@ -14,8 +14,8 @@ * Class FilterMapper * This class applies filters to Select based on SelectContainer configuration * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class FilterMapper { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php index 7925a619c8095..a61c691c0d5cd 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php @@ -10,8 +10,8 @@ * FilterStrategyInterface provides the interface to work with strategies * @api * @since 100.1.6 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ interface FilterStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php index 1e35a3c0352b1..3986cc617f06d 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php @@ -13,8 +13,8 @@ /** * This strategy handles static attributes * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class StaticAttributeStrategy implements FilterStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StockStatusFilter.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StockStatusFilter.php index f15e313ce06a6..0e3ba0d4e669f 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StockStatusFilter.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StockStatusFilter.php @@ -16,8 +16,8 @@ * Class StockStatusFilter * Adds filter by stock status to base select * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class StockStatusFilter { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php index bbec04eed0621..9d7e31ee3b6d1 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php @@ -16,8 +16,8 @@ * - The filter for dropdown or multi-select attribute * - The filter is Term filter * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class TermDropdownStrategy implements FilterStrategyInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/ApplyStockConditionToSelect.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/ApplyStockConditionToSelect.php index 64a2fdc25bb02..c28bc3485cf49 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/ApplyStockConditionToSelect.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/ApplyStockConditionToSelect.php @@ -14,8 +14,8 @@ /** * Apply stock condition to select. * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class ApplyStockConditionToSelect { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/SelectBuilder.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/SelectBuilder.php index 85281ce556889..007647db39b32 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/SelectBuilder.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy/SelectBuilder.php @@ -17,8 +17,8 @@ /** * Add joins to select. * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class SelectBuilder { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/VisibilityFilter.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/VisibilityFilter.php index c73651ad8007d..690ef9115edfe 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/VisibilityFilter.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/VisibilityFilter.php @@ -17,8 +17,8 @@ * Class VisibilityFilter * Applies filter by visibility to base select * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class VisibilityFilter { diff --git a/app/code/Magento/CatalogSearch/Model/Search/FiltersExtractor.php b/app/code/Magento/CatalogSearch/Model/Search/FiltersExtractor.php index 4a654acc920c5..55c8582979912 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/FiltersExtractor.php +++ b/app/code/Magento/CatalogSearch/Model/Search/FiltersExtractor.php @@ -13,8 +13,8 @@ * Class FiltersExtractor * Extracts filters from QueryInterface * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class FiltersExtractor { diff --git a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php index 8c4e5c432d5bc..906220db28dc1 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php +++ b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php @@ -26,8 +26,8 @@ /** * Build base Query for Index * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class IndexBuilder implements IndexBuilderInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/QueryChecker/FullTextSearchCheck.php b/app/code/Magento/CatalogSearch/Model/Search/QueryChecker/FullTextSearchCheck.php index a70f83d7ac91b..c122bae15cb0c 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/QueryChecker/FullTextSearchCheck.php +++ b/app/code/Magento/CatalogSearch/Model/Search/QueryChecker/FullTextSearchCheck.php @@ -13,8 +13,8 @@ /** * Class is responsible for checking if fulltext search is required for search query * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class FullTextSearchCheck { diff --git a/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php b/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php index 7256e11b8edbd..916e03f471493 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php +++ b/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php @@ -6,8 +6,8 @@ namespace Magento\CatalogSearch\Model\Search; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class ReaderPlugin { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php index 8e47a0674e2da..6e6aee08f926e 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php @@ -16,8 +16,8 @@ /** * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class RequestGenerator { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php index 5729b2544b3f4..ceff0ea2e5d17 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php @@ -11,8 +11,8 @@ use Magento\Framework\Search\Request\FilterInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class Decimal implements GeneratorInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php index 8db96ad04b20f..4321105a7e8fd 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php @@ -11,8 +11,8 @@ use Magento\Framework\Search\Request\FilterInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class General implements GeneratorInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php index 2eb7d06d31a5c..863f1fb7466c9 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php @@ -11,8 +11,8 @@ /** * @api * @since 100.1.6 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ interface GeneratorInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php index 5e4c2e0ff8ad6..68ca546b81919 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php @@ -9,8 +9,8 @@ /** * @api * @since 100.1.6 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class GeneratorResolver { diff --git a/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php b/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php index e32785a6a17af..f0eade4bfbcf5 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php +++ b/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainer.php @@ -12,8 +12,8 @@ /** * This class is a container for all data that is required for creating select query by search request * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class SelectContainer { diff --git a/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainerBuilder.php b/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainerBuilder.php index b6e60aabf484a..d5b7be8bf0106 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainerBuilder.php +++ b/app/code/Magento/CatalogSearch/Model/Search/SelectContainer/SelectContainerBuilder.php @@ -18,8 +18,8 @@ * Class SelectContainerBuilder * Class is responsible for SelectContainer creation and filling it with all required data * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class SelectContainerBuilder { diff --git a/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php b/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php index 001f9936c9586..6b18c4307f515 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php +++ b/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php @@ -25,8 +25,8 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class TableMapper { diff --git a/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php b/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php index cb7210813b056..956a1b2360f89 100644 --- a/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php +++ b/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php @@ -10,8 +10,8 @@ /** * Enable Product EAV indexer in configuration for MySQL search engine * - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class EnableEavIndexer { diff --git a/app/code/Magento/CatalogSearch/Setup/Patch/Data/SetInitialSearchWeightForAttributes.php b/app/code/Magento/CatalogSearch/Setup/Patch/Data/SetInitialSearchWeightForAttributes.php index 23429dd43e3fe..7f6dbe033e3a5 100644 --- a/app/code/Magento/CatalogSearch/Setup/Patch/Data/SetInitialSearchWeightForAttributes.php +++ b/app/code/Magento/CatalogSearch/Setup/Patch/Data/SetInitialSearchWeightForAttributes.php @@ -13,8 +13,8 @@ use Magento\Catalog\Api\ProductAttributeRepositoryInterface; /** - * @deprecated CatalogSearch will be removed in 2.4, and {@see \Magento\ElasticSearch} - * will replace it as the default search engine. + * @deprecated + * @see \Magento\ElasticSearch */ class SetInitialSearchWeightForAttributes implements DataPatchInterface, PatchVersionInterface { diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json index a823867296ffd..7bcb91e945417 100644 --- a/app/code/Magento/CatalogSearch/composer.json +++ b/app/code/Magento/CatalogSearch/composer.json @@ -1,6 +1,6 @@ { "name": "magento/module-catalog-search", - "description": "[Deprecated] CatalogSearch will be removed in 2.4, and ElasticSearch will replace it as the default search engine.", + "description": "Catalog search", "config": { "sort-packages": true }, From a7a43be69cad7ef6ace82ad97756b112ecd6415e Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Mon, 1 Oct 2018 09:56:38 +0300 Subject: [PATCH 129/812] MAGETWO-91650: Translation not working for product alerts - Revert changes --- app/code/Magento/ProductAlert/Model/Email.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/ProductAlert/Model/Email.php b/app/code/Magento/ProductAlert/Model/Email.php index 18adc54c2d660..7aee4ca01240d 100644 --- a/app/code/Magento/ProductAlert/Model/Email.php +++ b/app/code/Magento/ProductAlert/Model/Email.php @@ -359,7 +359,6 @@ public function send() $storeId = $this->storeId ?: (int) $this->_customer->getStoreId(); $store = $this->getStore($storeId); - $storeId = $store->getId(); $this->_appEmulation->startEnvironmentEmulation($storeId); @@ -408,6 +407,18 @@ public function send() return true; } + /** + * Retrieve the store for the email + * + * @param int $storeId + * @return StoreInterface + * @throws NoSuchEntityException + */ + private function getStore(int $storeId): StoreInterface + { + return $this->_storeManager->getStore($storeId); + } + /** * Retrieve the block for the email based on type * From cc00197d13d6244e32201e4c6bf00287e54747c5 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Mon, 1 Oct 2018 13:49:26 +0300 Subject: [PATCH 130/812] MAGETWO-91702: Shipping method Table Rates settings gets from wrong store - Fix website id for shipping --- app/code/Magento/Quote/Model/Quote/Address.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Quote/Model/Quote/Address.php b/app/code/Magento/Quote/Model/Quote/Address.php index 11beffe5711b9..140ace42afae1 100644 --- a/app/code/Magento/Quote/Model/Quote/Address.php +++ b/app/code/Magento/Quote/Model/Quote/Address.php @@ -1003,8 +1003,14 @@ public function requestShippingRates(\Magento\Quote\Model\Quote\Item\AbstractIte /** * Store and website identifiers specified from StoreManager */ - $request->setStoreId($this->getQuote()->getStoreId() ?? $this->storeManager->getStore()->getId()); - $request->setWebsiteId($this->storeManager->getWebsite()->getId()); + if ($this->getQuote()->getStoreId()) { + $storeId = $this->getQuote()->getStoreId(); + $request->setStoreId($storeId); + $request->setWebsiteId($this->storeManager->getStore($storeId)->getWebsiteId()); + } else { + $request->setStoreId($this->storeManager->getStore()->getId()); + $request->setWebsiteId($this->storeManager->getWebsite()->getId()); + } $request->setFreeShipping($this->getFreeShipping()); /** * Currencies need to convert in free shipping From d9ee86dc4d2e7072dd768375ce393f4771c175e6 Mon Sep 17 00:00:00 2001 From: Oleg Onufer <linkedddd@gmail.com> Date: Mon, 1 Oct 2018 14:40:49 +0300 Subject: [PATCH 131/812] MAGETWO-95307: Url-rewrites for product in anchor categories --- .../Mftf/Page/AdminUrlRewriteIndexPage.xml | 14 ++++ .../Section/AdminUrlRewriteIndexSection.xml | 16 ++++ ...writesForProductInAnchorCategoriesTest.xml | 81 +++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteIndexPage.xml create mode 100644 app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml create mode 100644 app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteIndexPage.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteIndexPage.xml new file mode 100644 index 0000000000000..c7c450a00a0c3 --- /dev/null +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteIndexPage.xml @@ -0,0 +1,14 @@ +<?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="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="AdminUrlRewriteIndexPage" url="admin/url_rewrite/index/" area="admin" module="Magento_UrlRewrite"> + <section name="AdminUrlRewriteIndexSection"/> + </page> +</pages> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml new file mode 100644 index 0000000000000..a7a17482a8ec1 --- /dev/null +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminUrlRewriteIndexSection"> + <element name="requestPathSearchField" type="input" selector="#urlrewriteGrid_filter_request_path"/> + <element name="requestPathColumns" type="text" selector="//td[@data-column='request_path'][not(input)]"/> + <element name="search" type="button" selector="[data-action='grid-filter-apply']" timeout="10"/> + </section> +</sections> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml new file mode 100644 index 0000000000000..8591b0f93f926 --- /dev/null +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml @@ -0,0 +1,81 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminUrlRewritesForProductInAnchorCategoriesTest"> + <annotations> + <features value="Url Rewrite"/> + <stories value="Url-rewrites for product in anchor categories"/> + <title value="Url-rewrites for product in anchor categories"/> + <description value="For a product with category that has parent anchor categories, the rewrites is created when the category/product is saved."/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-69826"/> + <group value="UrlRewrite"/> + </annotations> + + <!-- Preconditions--> + <!-- Create 3 categories --> + <before> + <createData entity="SimpleSubCategory" stepKey="simpleSubCategory1"/> + <createData entity="SubCategoryWithParent" stepKey="simpleSubCategory2"> + <requiredEntity createDataKey="simpleSubCategory1"/> + </createData> + <createData entity="SubCategoryWithParent" stepKey="simpleSubCategory3"> + <requiredEntity createDataKey="simpleSubCategory2"/> + </createData> + <!-- Create Simple product 1 and assign it to Category 3 --> + <createData entity="ApiSimpleProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="simpleSubCategory3"/> + </createData> + </before> + <after> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> + <deleteData createDataKey="simpleSubCategory3" stepKey="deletesimpleSubCategory3"/> + <deleteData createDataKey="simpleSubCategory2" stepKey="deletesimpleSubCategory2"/> + <deleteData createDataKey="simpleSubCategory1" stepKey="deletesimpleSubCategory1"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + </after> + <!-- Steps --> + <!-- 1. Log in to Admin --> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + + <!-- 2. Open Marketing - SEO & Search - URL Rewrites --> + <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage"/> + <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName"/> + <click selector="{{AdminUrlRewriteIndexSection.search}}" stepKey="clickSearchButton"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue1"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue2"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue3"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue4"/> + + <!-- 3. Edit Category 1 for DEFAULT Store View: --> + <actionGroup ref="switchCategoryStoreView" stepKey="SwitchStoreView"> + <argument name="Store" value="_defaultStore.name"/> + <argument name="CatName" value="SimpleSubCategory.name"/> + </actionGroup> + <click selector="{{AdminCategorySEOSection.SectionHeader}}" stepKey="openSeoSection2"/> + <uncheckOption selector="{{AdminCategorySEOSection.UrlKeyDefaultValueCheckbox}}" stepKey="uncheckRedirect2"/> + <fillField selector="{{AdminCategorySEOSection.UrlKeyInput}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new" stepKey="changeURLKey"/> + + <!-- 4. Save Category 1 --> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> + <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="assertSuccessMessageAfterSaved"/> + + <!-- 5. Open Marketing - SEO & Search - URL Rewrites --> + <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage2"/> + <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName2"/> + <click selector="{{AdminUrlRewriteIndexSection.search}}" stepKey="clickSearchButton2"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue1"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.name$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue2"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.name$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue3"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.name$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue4"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue5"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue6"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue7"/> + </test> +</tests> From 16a7f0babc8cfd4420dfea32c35449745449791b Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:05:26 -0300 Subject: [PATCH 132/812] Use @inheritdoc and revert back code change --- .../Framework/Stdlib/DateTime/Timezone.php | 125 +++--------------- 1 file changed, 15 insertions(+), 110 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 2bfa465c8268f..fbda76a8e3616 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -85,9 +85,7 @@ public function __construct( } /** - * Return path to default timezone - * - * @return string + * @inheritdoc */ public function getDefaultTimezonePath() { @@ -95,9 +93,7 @@ public function getDefaultTimezonePath() } /** - * Retrieve timezone code - * - * @return string + * @inheritdoc */ public function getDefaultTimezone() { @@ -105,11 +101,7 @@ public function getDefaultTimezone() } /** - * Gets the scope config timezone - * - * @param string $scopeType - * @param string $scopeCode - * @return string + * @inheritdoc */ public function getConfigTimezone($scopeType = null, $scopeCode = null) { @@ -121,10 +113,7 @@ public function getConfigTimezone($scopeType = null, $scopeCode = null) } /** - * Retrieve ISO date format - * - * @param int $type - * @return string + * @inheritdoc */ public function getDateFormat($type = \IntlDateFormatter::SHORT) { @@ -136,9 +125,7 @@ public function getDateFormat($type = \IntlDateFormatter::SHORT) } /** - * Retrieve short date format with 4-digit year - * - * @return string + * @inheritdoc */ public function getDateFormatWithLongYear() { @@ -150,10 +137,7 @@ public function getDateFormatWithLongYear() } /** - * Retrieve ISO time format - * - * @param string $type - * @return string + * @inheritdoc */ public function getTimeFormat($type = \IntlDateFormatter::SHORT) { @@ -165,10 +149,7 @@ public function getTimeFormat($type = \IntlDateFormatter::SHORT) } /** - * Retrieve ISO datetime format - * - * @param string $type - * @return string + * @inheritdoc */ public function getDateTimeFormat($type) { @@ -176,13 +157,7 @@ public function getDateTimeFormat($type) } /** - * Create \DateTime object for current locale - * - * @param mixed $date - * @param string $locale - * @param bool $useTimezone - * @param bool $includeTime - * @return \DateTime + * @inheritdoc */ public function date($date = null, $locale = null, $useTimezone = true, $includeTime = true) { @@ -216,12 +191,7 @@ public function date($date = null, $locale = null, $useTimezone = true, $include } /** - * Create \DateTime object with date converted to scope timezone and scope Locale - * - * @param mixed $scope Information about scope - * @param string|integer|\DateTime|array|null $date date in UTC - * @param boolean $includeTime flag for including time to date - * @return \DateTime + * @inheritdoc */ public function scopeDate($scope = null, $date = null, $includeTime = false) { @@ -234,12 +204,7 @@ public function scopeDate($scope = null, $date = null, $includeTime = false) } /** - * Format date using current locale options and time zone. - * - * @param \DateTime|null $date - * @param int $format - * @param bool $showTime - * @return string + * @inheritdoc */ public function formatDate($date = null, $format = \IntlDateFormatter::SHORT, $showTime = false) { @@ -253,12 +218,7 @@ public function formatDate($date = null, $format = \IntlDateFormatter::SHORT, $s } /** - * Get scope timestamp - * - * Timestamp will be built with scope timezone settings - * - * @param mixed $scope - * @return int + * @inheritdoc */ public function scopeTimeStamp($scope = null) { @@ -271,12 +231,7 @@ public function scopeTimeStamp($scope = null) } /** - * Checks if current date of the given scope (in the scope timezone) is within the range - * - * @param int|string|\Magento\Framework\App\ScopeInterface $scope - * @param string|null $dateFrom - * @param string|null $dateTo - * @return bool + * @inheritdoc */ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) { @@ -302,13 +257,7 @@ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) } /** - * @param string|\DateTimeInterface $date - * @param int $dateType - * @param int $timeType - * @param string|null $locale - * @param string|null $timezone - * @param string|null $pattern - * @return string + * @inheritdoc */ public function formatDateTime( $date, @@ -344,56 +293,15 @@ public function formatDateTime( } /** - * Convert date from config timezone to Utc. - * - * If pass \DateTime object as argument be sure that timezone is the same with config timezone - * - * @param string|\DateTimeInterface $date - * @param string $format - * @throws LocalizedException - * @return string - * @deprecated + * @inheritdoc */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') - { - return $this->convertConfigTimeToUtcWithPattern($date, $format); - } - - /** - * Convert date from config timezone to Utc. - * - * If pass \DateTime object as argument be sure that timezone is the same with config timezone - * - * @param string|\DateTimeInterface $date - * @param string $format - * @param string $pattern - * @throws LocalizedException - * @return string - * @deprecated - */ - public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = null) { if (!($date instanceof \DateTimeInterface)) { if ($date instanceof \DateTimeImmutable) { $date = new \DateTime($date->format('Y-m-d H:i:s'), new \DateTimeZone($this->getConfigTimezone())); } else { - $locale = $this->_localeResolver->getLocale(); - if ($locale === null) { - $pattern = 'Y-M-dd HH:mm:ss'; - } - $formatter = new \IntlDateFormatter( - $locale, - \IntlDateFormatter::MEDIUM, - \IntlDateFormatter::MEDIUM, - $this->getConfigTimezone(), - null, - $pattern - ); - $unixTime = $formatter->parse($date); - $dateTime = new DateTime($this); - - $dateUniversal = $dateTime->gmtDate(null, $unixTime); - $date = new \DateTime($dateUniversal, new \DateTimeZone($this->getConfigTimezone())); + $date = new \DateTime($date, new \DateTimeZone($this->getConfigTimezone())); } } else { if ($date->getTimezone()->getName() !== $this->getConfigTimezone()) { @@ -405,13 +313,10 @@ public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s' ); } } - $date->setTimezone(new \DateTimeZone('UTC')); - return $date->format($format); } - /** * Retrieve date with time * From 9315dd6963834ec6299eed8395add8bdb7bb7895 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:07:53 -0300 Subject: [PATCH 133/812] Revert back code change to fix BiC --- .../Framework/Stdlib/DateTime/Timezone.php | 16 ++++++++++++++-- .../Stdlib/DateTime/TimezoneInterface.php | 14 -------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index fbda76a8e3616..5dbaf093698a1 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -257,7 +257,13 @@ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) } /** - * @inheritdoc + * @param string|\DateTimeInterface $date + * @param int $dateType + * @param int $timeType + * @param string|null $locale + * @param string|null $timezone + * @param string|null $pattern + * @return string */ public function formatDateTime( $date, @@ -293,7 +299,13 @@ public function formatDateTime( } /** - * @inheritdoc + * Convert date from config timezone to Utc. + * If pass \DateTime object as argument be sure that timezone is the same with config timezone + * + * @param string|\DateTimeInterface $date + * @param string $format + * @throws LocalizedException + * @return string */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') { diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index 17ba759a4d763..e8e20070c55de 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -152,18 +152,4 @@ public function formatDateTime( * @deprecated */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s'); - - /** - * Convert date from config timezone to Utc. - * - * If pass \DateTime object as argument be sure that timezone is the same with config timezone - * - * @param string|\DateTimeInterface $date - * @param string $format - * @param string $pattern - * @throws LocalizedException - * @return string - * @deprecated - */ - public function convertConfigTimeToUtcWithPattern($date, $format = 'Y-m-d H:i:s', $pattern = 'Y-m-d H:i:s'); } From 42cd2282007b0fc191413f8d483c58c6729823fc Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:08:38 -0300 Subject: [PATCH 134/812] Revert back @deprecated tag --- .../Magento/Framework/Stdlib/DateTime/TimezoneInterface.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index e8e20070c55de..11e9a22d8cea5 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -149,7 +149,6 @@ public function formatDateTime( * @param string $format * @throws LocalizedException * @return string - * @deprecated */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s'); } From ddeaf36c942f17f720cc720c840aeb844e93efbf Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:09:24 -0300 Subject: [PATCH 135/812] Revert back new lines --- lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 5dbaf093698a1..2bc0b36cb6ef7 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -325,7 +325,9 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') ); } } + $date->setTimezone(new \DateTimeZone('UTC')); + return $date->format($format); } From 6cc903442a668370898ee352871510f48a72bc21 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:10:48 -0300 Subject: [PATCH 136/812] Revert back documentation change in API interface --- .../Magento/Framework/Stdlib/DateTime/Timezone.php | 2 +- .../Framework/Stdlib/DateTime/TimezoneInterface.php | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 2bc0b36cb6ef7..8534e798481cb 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -327,7 +327,7 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') } $date->setTimezone(new \DateTimeZone('UTC')); - + return $date->format($format); } diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index 11e9a22d8cea5..217bf5b7f010d 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -104,7 +104,6 @@ public function formatDate( /** * Gets the scope config timezone - * * @param string $scopeType * @param string $scopeCode * @return string @@ -122,7 +121,6 @@ public function getConfigTimezone($scopeType = null, $scopeCode = null); public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null); /** - * * @param string|\DateTimeInterface $date * @param int $dateType * @param int $timeType @@ -141,14 +139,10 @@ public function formatDateTime( ); /** - * Convert date from config timezone to Utc. - * - * If pass \DateTime object as argument be sure that timezone is the same with config timezone - * * @param string|\DateTimeInterface $date * @param string $format - * @throws LocalizedException * @return string + * @since 100.1.0 */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s'); } From 28617c01e62941eaa68df8b6ea72a958c6f5367c Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:11:51 -0300 Subject: [PATCH 137/812] Fix documentation change for code smell --- .../Magento/Framework/Stdlib/DateTime/TimezoneInterface.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index 217bf5b7f010d..c2ef294daf0c8 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -104,6 +104,7 @@ public function formatDate( /** * Gets the scope config timezone + * * @param string $scopeType * @param string $scopeCode * @return string From fd0ab037a74cc5d78d02c603adbd5cf10cb92c88 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 1 Oct 2018 09:12:38 -0300 Subject: [PATCH 138/812] Fix documentation --- .../Magento/Framework/Stdlib/DateTime/TimezoneInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index c2ef294daf0c8..4aff80161ef80 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -104,7 +104,7 @@ public function formatDate( /** * Gets the scope config timezone - * + * * @param string $scopeType * @param string $scopeCode * @return string From 94d735e033314f6c384f0eba51647d9219f62ed8 Mon Sep 17 00:00:00 2001 From: Oleg Onufer <linkedddd@gmail.com> Date: Mon, 1 Oct 2018 17:06:00 +0300 Subject: [PATCH 139/812] MAGETWO-95307: Url-rewrites for product in anchor categories --- .../AdminUrlRewritesForProductInAnchorCategoriesTest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml index 8591b0f93f926..22c27042aad52 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml @@ -71,9 +71,9 @@ <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName2"/> <click selector="{{AdminUrlRewriteIndexSection.search}}" stepKey="clickSearchButton2"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue1"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.name$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue2"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.name$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue3"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.name$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue4"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue2"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue3"/> + <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue4"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue5"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue6"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue7"/> From 772ae6b8df140d0b88f804c5ddf18266fdc18f13 Mon Sep 17 00:00:00 2001 From: Oleg Onufer <linkedddd@gmail.com> Date: Mon, 1 Oct 2018 17:34:22 +0300 Subject: [PATCH 140/812] MAGETWO-95307: Url-rewrites for product in anchor categories --- .../Test/Mftf/Section/AdminUrlRewriteIndexSection.xml | 1 - .../AdminUrlRewritesForProductInAnchorCategoriesTest.xml | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml index a7a17482a8ec1..3c445b5cf3e6f 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml @@ -11,6 +11,5 @@ <section name="AdminUrlRewriteIndexSection"> <element name="requestPathSearchField" type="input" selector="#urlrewriteGrid_filter_request_path"/> <element name="requestPathColumns" type="text" selector="//td[@data-column='request_path'][not(input)]"/> - <element name="search" type="button" selector="[data-action='grid-filter-apply']" timeout="10"/> </section> </sections> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml index 22c27042aad52..562d414a63ddb 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml @@ -15,7 +15,7 @@ <description value="For a product with category that has parent anchor categories, the rewrites is created when the category/product is saved."/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-69826"/> - <group value="UrlRewrite"/> + <group value="urlRewrite"/> </annotations> <!-- Preconditions--> @@ -47,7 +47,7 @@ <!-- 2. Open Marketing - SEO & Search - URL Rewrites --> <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage"/> <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName"/> - <click selector="{{AdminUrlRewriteIndexSection.search}}" stepKey="clickSearchButton"/> + <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickSearchButton"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue1"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue2"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue3"/> @@ -69,7 +69,7 @@ <!-- 5. Open Marketing - SEO & Search - URL Rewrites --> <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage2"/> <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName2"/> - <click selector="{{AdminUrlRewriteIndexSection.search}}" stepKey="clickSearchButton2"/> + <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickSearchButton2"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue1"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue2"/> <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue3"/> From 720a5c63e11d75615e2f3de6c452f5aa097ba0fe Mon Sep 17 00:00:00 2001 From: Yurii Borysov <yurii_borysov@epam.com> Date: Mon, 1 Oct 2018 17:51:19 +0300 Subject: [PATCH 141/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix CR Issues --- .../GroupedProduct/view/adminhtml/web/css/grouped-product.css | 2 +- .../view/adminhtml/web/js/grouped-product-grid.js | 2 +- .../view/adminhtml/web/template/components/position.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css b/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css index 1916f222a499b..cd0aa25ae1f88 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css @@ -102,4 +102,4 @@ .icon-backward:before { content: '\e619'; -} \ No newline at end of file +} diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 0a585eb92958d..7c9563bb1a0ce 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -206,4 +206,4 @@ define([ }); -}); \ No newline at end of file +}); diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html b/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html index dbfeff2e32c04..050fb3c2898ce 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/template/components/position.html @@ -16,4 +16,4 @@ "> <span>Bottom</span> </a> -</div> \ No newline at end of file +</div> From b77c7acf6ee5dca25ab9431e83de91bb00b58795 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Mon, 1 Oct 2018 17:59:51 +0300 Subject: [PATCH 142/812] MAGETWO-58210: Import Products sets default behaviour as append, need add_update - Added "add_update" behavior for checking by default --- .../ImportExport/Model/Import/Entity/AbstractEntity.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php index e965e8ad207fd..96704667bfc61 100644 --- a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php +++ b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php @@ -554,6 +554,7 @@ public function getBehavior() $this->_parameters['behavior'] ) || $this->_parameters['behavior'] != ImportExport::BEHAVIOR_APPEND && + $this->_parameters['behavior'] != ImportExport::BEHAVIOR_ADD_UPDATE && $this->_parameters['behavior'] != ImportExport::BEHAVIOR_REPLACE && $this->_parameters['behavior'] != ImportExport::BEHAVIOR_DELETE ) { @@ -828,6 +829,8 @@ public function validateData() } /** + * Get instance of error aggregator. + * * @return ProcessingErrorAggregatorInterface */ public function getErrorAggregator() From 5f1b9a0f4ec9d6276d811c166b5a0345f4e74222 Mon Sep 17 00:00:00 2001 From: Dave Macaulay <dmacaulay@magento.com> Date: Mon, 1 Oct 2018 18:16:06 +0200 Subject: [PATCH 143/812] MC-4189: IE11 - PageBuilder Does Not Load - Revert changes to es6-collections.js --- lib/web/es6-collections.js | 273 ++++++++++++++++++++++++++++++------- 1 file changed, 227 insertions(+), 46 deletions(-) diff --git a/lib/web/es6-collections.js b/lib/web/es6-collections.js index ed8e80c1fd07e..50ff560e53a8a 100644 --- a/lib/web/es6-collections.js +++ b/lib/web/es6-collections.js @@ -1,46 +1,227 @@ -/* - * Copyright 2012 The Polymer Authors. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -if (typeof WeakMap === 'undefined') { - (function() { - var defineProperty = Object.defineProperty; - var counter = Date.now() % 1e9; - - var WeakMap = function() { - this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__'); - }; - - WeakMap.prototype = { - set: function(key, value) { - var entry = key[this.name]; - if (entry && entry[0] === key) - entry[1] = value; - else - defineProperty(key, this.name, {value: [key, value], writable: true}); - return this; - }, - get: function(key) { - var entry; - return (entry = key[this.name]) && entry[0] === key ? - entry[1] : undefined; - }, - delete: function(key) { - var entry = key[this.name]; - if (!entry) return false; - var hasValue = entry[0] === key; - entry[0] = entry[1] = undefined; - return hasValue; - }, - has: function(key) { - var entry = key[this.name]; - if (!entry) return false; - return entry[0] === key; - } - }; - - window.WeakMap = WeakMap; - })(); -} \ No newline at end of file +(function (exports) {'use strict'; + //shared pointer + var i; + //shortcuts + var defineProperty = Object.defineProperty, is = function(a,b) { return isNaN(a)? isNaN(b): a === b; }; + + + //Polyfill global objects + if (typeof WeakMap == 'undefined') { + exports.WeakMap = createCollection({ + // WeakMap#delete(key:void*):boolean + 'delete': sharedDelete, + // WeakMap#clear(): + clear: sharedClear, + // WeakMap#get(key:void*):void* + get: sharedGet, + // WeakMap#has(key:void*):boolean + has: mapHas, + // WeakMap#set(key:void*, value:void*):void + set: sharedSet + }, true); + } + + if (typeof Map == 'undefined' || typeof ((new Map).values) !== 'function' || !(new Map).values().next) { + exports.Map = createCollection({ + // WeakMap#delete(key:void*):boolean + 'delete': sharedDelete, + //:was Map#get(key:void*[, d3fault:void*]):void* + // Map#has(key:void*):boolean + has: mapHas, + // Map#get(key:void*):boolean + get: sharedGet, + // Map#set(key:void*, value:void*):void + set: sharedSet, + // Map#keys(void):Iterator + keys: sharedKeys, + // Map#values(void):Iterator + values: sharedValues, + // Map#entries(void):Iterator + entries: mapEntries, + // Map#forEach(callback:Function, context:void*):void ==> callback.call(context, key, value, mapObject) === not in specs` + forEach: sharedForEach, + // Map#clear(): + clear: sharedClear + }); + } + + if (typeof Set == 'undefined' || typeof ((new Set).values) !== 'function' || !(new Set).values().next) { + exports.Set = createCollection({ + // Set#has(value:void*):boolean + has: setHas, + // Set#add(value:void*):boolean + add: sharedAdd, + // Set#delete(key:void*):boolean + 'delete': sharedDelete, + // Set#clear(): + clear: sharedClear, + // Set#keys(void):Iterator + keys: sharedValues, // specs actually say "the same function object as the initial value of the values property" + // Set#values(void):Iterator + values: sharedValues, + // Set#entries(void):Iterator + entries: setEntries, + // Set#forEach(callback:Function, context:void*):void ==> callback.call(context, value, index) === not in specs + forEach: sharedForEach + }); + } + + if (typeof WeakSet == 'undefined') { + exports.WeakSet = createCollection({ + // WeakSet#delete(key:void*):boolean + 'delete': sharedDelete, + // WeakSet#add(value:void*):boolean + add: sharedAdd, + // WeakSet#clear(): + clear: sharedClear, + // WeakSet#has(value:void*):boolean + has: setHas + }, true); + } + + + /** + * ES6 collection constructor + * @return {Function} a collection class + */ + function createCollection(proto, objectOnly){ + function Collection(a){ + if (!this || this.constructor !== Collection) return new Collection(a); + this._keys = []; + this._values = []; + this._itp = []; // iteration pointers + this.objectOnly = objectOnly; + + //parse initial iterable argument passed + if (a) init.call(this, a); + } + + //define size for non object-only collections + if (!objectOnly) { + defineProperty(proto, 'size', { + get: sharedSize + }); + } + + //set prototype + proto.constructor = Collection; + Collection.prototype = proto; + + return Collection; + } + + + /** parse initial iterable argument passed */ + function init(a){ + var i; + //init Set argument, like `[1,2,3,{}]` + if (this.add) + a.forEach(this.add, this); + //init Map argument like `[[1,2], [{}, 4]]` + else + a.forEach(function(a){this.set(a[0],a[1])}, this); + } + + + /** delete */ + function sharedDelete(key) { + if (this.has(key)) { + this._keys.splice(i, 1); + this._values.splice(i, 1); + // update iteration pointers + this._itp.forEach(function(p) { if (i < p[0]) p[0]--; }); + } + // Aurora here does it while Canary doesn't + return -1 < i; + }; + + function sharedGet(key) { + return this.has(key) ? this._values[i] : undefined; + } + + function has(list, key) { + if (this.objectOnly && key !== Object(key)) + throw new TypeError("Invalid value used as weak collection key"); + //NaN or 0 passed + if (key != key || key === 0) for (i = list.length; i-- && !is(list[i], key);){} + else i = list.indexOf(key); + return -1 < i; + } + + function setHas(value) { + return has.call(this, this._values, value); + } + + function mapHas(value) { + return has.call(this, this._keys, value); + } + + /** @chainable */ + function sharedSet(key, value) { + this.has(key) ? + this._values[i] = value + : + this._values[this._keys.push(key) - 1] = value + ; + return this; + } + + /** @chainable */ + function sharedAdd(value) { + if (!this.has(value)) this._values.push(value); + return this; + } + + function sharedClear() { + this._values.length = 0; + } + + /** keys, values, and iterate related methods */ + function sharedKeys() { + return sharedIterator(this._itp, this._keys); + } + + function sharedValues() { + return sharedIterator(this._itp, this._values); + } + + function mapEntries() { + return sharedIterator(this._itp, this._keys, this._values); + } + + function setEntries() { + return sharedIterator(this._itp, this._values, this._values); + } + + function sharedIterator(itp, array, array2) { + var p = [0], done = false; + itp.push(p); + return { + next: function() { + var v, k = p[0]; + if (!done && k < array.length) { + v = array2 ? [array[k], array2[k]]: array[k]; + p[0]++; + } else { + done = true; + itp.splice(itp.indexOf(p), 1); + } + return { done: done, value: v }; + } + }; + } + + function sharedSize() { + return this._values.length; + } + + function sharedForEach(callback, context) { + var it = this.entries(); + for (;;) { + var r = it.next(); + if (r.done) break; + callback.call(context, r.value[1], r.value[0], this); + } + } + +})(typeof exports != 'undefined' && typeof global != 'undefined' ? global : window ); \ No newline at end of file From ec5d9b7f171e76c0285c6e683a4b2da5902c2f78 Mon Sep 17 00:00:00 2001 From: lucascalazans <calazans95@hotmail.com> Date: Mon, 1 Oct 2018 15:31:32 -0300 Subject: [PATCH 144/812] #17744 Adding isVirtual mock to quote instance && fixs --- .../view/frontend/web/js/model/checkout-data-resolver.js | 3 +++ .../frontend/js/view/payment/method-renderer/paypal.test.js | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 6f4c99438610b..d75da01b5ded5 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -231,13 +231,16 @@ define([ isBillingAddressInitialized = addressList.some(function (addrs) { if (addrs.isDefaultBilling()) { selectBillingAddress(addrs); + return true; } + return false; }); } shippingAddress = quote.shippingAddress(); + if (!isBillingAddressInitialized && shippingAddress && shippingAddress.canUseForBilling() && diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js index 6fabc513da9af..f9475d78607f4 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js @@ -24,7 +24,10 @@ define([ paymentMethod: ko.observable(), totals: ko.observable({ 'base_grand_total': 0 - }) + }), + isVirtual: function () { + return false; + } }, 'Magento_Braintree/js/view/payment/adapter': { config: {}, From f3bad34fe9156f1fe2d2e2d4a4a7d8a244107085 Mon Sep 17 00:00:00 2001 From: lucascalazans <calazans95@hotmail.com> Date: Mon, 1 Oct 2018 16:55:30 -0300 Subject: [PATCH 145/812] #17744 Adding others isVirtual mock and annotations --- .../js/view/payment/method-renderer/cc-form.test.js | 7 ++++++- .../js/view/payment/method-renderer/paypal.test.js | 2 ++ .../method-renderer/paypal-express-abstract.test.js | 6 +++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/cc-form.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/cc-form.test.js index 84db685c02987..8fdef2cbaadbb 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/cc-form.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/cc-form.test.js @@ -19,7 +19,12 @@ define([ billingAddress: ko.observable(), shippingAddress: ko.observable(), paymentMethod: ko.observable(), - totals: ko.observable({}) + totals: ko.observable({}), + + /** Stub */ + isVirtual: function () { + return false; + } }, 'Magento_Braintree/js/view/payment/validator-handler': jasmine.createSpyObj( 'validator-handler', diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js index f9475d78607f4..4fc73caf7e14b 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/paypal.test.js @@ -25,6 +25,8 @@ define([ totals: ko.observable({ 'base_grand_total': 0 }), + + /** Stub */ isVirtual: function () { return false; } diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js index f05338ad1e7d2..9950c89ce3c9d 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js @@ -28,8 +28,12 @@ define([ billingAddress: ko.observable(), shippingAddress: ko.observable(), paymentMethod: ko.observable(), - totals: ko.observable({}) + totals: ko.observable({}), + /** Stub */ + isVirtual: function () { + return false; + } }, 'Magento_Checkout/js/action/set-payment-information': setPaymentMock, 'Magento_Checkout/js/model/payment/additional-validators': { From e12044867b9d59bf44b5baedec539e79f9a2c020 Mon Sep 17 00:00:00 2001 From: stefank <stefan.koch@adyen.com> Date: Mon, 1 Oct 2018 22:33:31 +0200 Subject: [PATCH 146/812] Support of error pages behind a load balancer that serves HTTPS but accesses the webserver on HTTP. Without this css is loaded on HTTP from a document loaded over HTTPS --- pub/errors/processor.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 7240707f642c2..6add4e8cb3ad1 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -265,7 +265,8 @@ public function getHostUrl() $host = 'localhost'; } - $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off'); + // HTTP_X_FORWARDED_PROTO to check whether a webserver using HTTP is behind a load balancer serving HTTPS + $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off') || $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'; $url = ($isSecure ? 'https://' : 'http://') . $host; if (!empty($_SERVER['SERVER_PORT']) && !in_array($_SERVER['SERVER_PORT'], [80, 443]) From 440e9eb40884e12236f820f9ba1e52cb704e702f Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Tue, 2 Oct 2018 09:47:30 +0300 Subject: [PATCH 147/812] MAGETWO-91711: Unable to delete downloadable product links if sample links are not deleted - Set empty arrays if info doesn't come from request. --- .../Product/Initialization/Helper/Plugin/Downloadable.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php index f56b219f72db2..a283891afc406 100644 --- a/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php +++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php @@ -11,6 +11,9 @@ use Magento\Downloadable\Api\Data\SampleInterfaceFactory; use Magento\Downloadable\Api\Data\LinkInterfaceFactory; +/** + * Class for initialization downloadable info from request. + */ class Downloadable { /** @@ -92,6 +95,8 @@ public function afterInitialize( } } $extension->setDownloadableProductLinks($links); + } else { + $extension->setDownloadableProductLinks([]); } if (isset($downloadable['sample']) && is_array($downloadable['sample'])) { $samples = []; @@ -107,6 +112,8 @@ public function afterInitialize( } } $extension->setDownloadableProductSamples($samples); + } else { + $extension->setDownloadableProductSamples([]); } $product->setExtensionAttributes($extension); if ($product->getLinksPurchasedSeparately()) { From 45eecf58054aa9c22cdae6fb7f397371d79ddf75 Mon Sep 17 00:00:00 2001 From: Oleg Onufer <linkedddd@gmail.com> Date: Tue, 2 Oct 2018 11:46:32 +0300 Subject: [PATCH 148/812] MAGETWO-95307: Url-rewrites for product in anchor categories --- .../Section/AdminUrlRewriteIndexSection.xml | 4 +-- ...writesForProductInAnchorCategoriesTest.xml | 34 +++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml index 3c445b5cf3e6f..0880b50950e15 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteIndexSection.xml @@ -9,7 +9,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminUrlRewriteIndexSection"> - <element name="requestPathSearchField" type="input" selector="#urlrewriteGrid_filter_request_path"/> - <element name="requestPathColumns" type="text" selector="//td[@data-column='request_path'][not(input)]"/> + <element name="requestPathFilter" type="input" selector="#urlrewriteGrid_filter_request_path"/> + <element name="requestPathColumnValue" type="text" selector="//*[@id='urlrewriteGrid']//tbody//td[@data-column='request_path' and normalize-space(.)='{{columnValue}}']" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml index 562d414a63ddb..0d9df9176d2b5 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductInAnchorCategoriesTest.xml @@ -35,8 +35,6 @@ </before> <after> <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> - <deleteData createDataKey="simpleSubCategory3" stepKey="deletesimpleSubCategory3"/> - <deleteData createDataKey="simpleSubCategory2" stepKey="deletesimpleSubCategory2"/> <deleteData createDataKey="simpleSubCategory1" stepKey="deletesimpleSubCategory1"/> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> </after> @@ -46,36 +44,36 @@ <!-- 2. Open Marketing - SEO & Search - URL Rewrites --> <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage"/> - <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName"/> + <fillField selector="{{AdminUrlRewriteIndexSection.requestPathFilter}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName"/> <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickSearchButton"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue1"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue2"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue3"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeValue4"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeValue1"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeValue2"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeValue3"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeValue4"/> <!-- 3. Edit Category 1 for DEFAULT Store View: --> - <actionGroup ref="switchCategoryStoreView" stepKey="SwitchStoreView"> + <actionGroup ref="switchCategoryStoreView" stepKey="switchStoreView"> <argument name="Store" value="_defaultStore.name"/> - <argument name="CatName" value="SimpleSubCategory.name"/> + <argument name="CatName" value="$$simpleSubCategory1.name$$"/> </actionGroup> <click selector="{{AdminCategorySEOSection.SectionHeader}}" stepKey="openSeoSection2"/> <uncheckOption selector="{{AdminCategorySEOSection.UrlKeyDefaultValueCheckbox}}" stepKey="uncheckRedirect2"/> <fillField selector="{{AdminCategorySEOSection.UrlKeyInput}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new" stepKey="changeURLKey"/> - + <checkOption selector="{{AdminCategorySEOSection.UrlKeyRedirectCheckbox}}" stepKey="checkUrlKeyRedirect"/> <!-- 4. Save Category 1 --> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="assertSuccessMessageAfterSaved"/> <!-- 5. Open Marketing - SEO & Search - URL Rewrites --> <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage2"/> - <fillField selector="{{AdminUrlRewriteIndexSection.requestPathSearchField}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName2"/> + <fillField selector="{{AdminUrlRewriteIndexSection.requestPathFilter}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName2"/> <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickSearchButton2"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue1"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue2"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue3"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue4"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue5"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue6"/> - <see selector="{{AdminUrlRewriteIndexSection.requestPathColumns}}" userInput="$simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="seeInListValue7"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue1"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue2"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue3"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue4"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$-new/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue5"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue6"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$-new/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeInListValue7"/> </test> </tests> From 2c651382be48db9916469d286227a400c5af1ef5 Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Mon, 1 Oct 2018 19:36:56 +0300 Subject: [PATCH 149/812] MAGETWO-95315: [2.3] Joins to grid collections causes MySQL exception due to ambiguous where clause --- .../ResourceModel/Order/Grid/Collection.php | 15 +++++++ .../Order/Grid/CollectionTest.php | 45 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/Order/Grid/CollectionTest.php diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Grid/Collection.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Grid/Collection.php index f6dd8f8527a53..82c612c1a781d 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Order/Grid/Collection.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Grid/Collection.php @@ -35,4 +35,19 @@ public function __construct( ) { parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $mainTable, $resourceModel); } + + /** + * @inheritdoc + */ + protected function _initSelect() + { + parent::_initSelect(); + + $tableDescription = $this->getConnection()->describeTable($this->getMainTable()); + foreach ($tableDescription as $columnInfo) { + $this->addFilterToMap($columnInfo['COLUMN_NAME'], 'main_table.' . $columnInfo['COLUMN_NAME']); + } + + return $this; + } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/Order/Grid/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/Order/Grid/CollectionTest.php new file mode 100644 index 0000000000000..1649706a51f6b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/Order/Grid/CollectionTest.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\Model\ResourceModel\Order\Grid; + +use Magento\TestFramework\Helper\Bootstrap; + +class CollectionTest extends \PHPUnit\Framework\TestCase +{ + /** + * Tests collection properties. + * + * @throws \ReflectionException + * @return void + */ + public function testCollectionCreate(): void + { + $objectManager = Bootstrap::getObjectManager(); + + /** @var Collection $gridCollection */ + $gridCollection = $objectManager->get(Collection::class); + $tableDescription = $gridCollection->getConnection() + ->describeTable($gridCollection->getMainTable()); + + $mapper = new \ReflectionMethod( + Collection::class, + '_getMapper' + ); + $mapper->setAccessible(true); + $map = $mapper->invoke($gridCollection); + + self::assertInternalType('array', $map); + self::assertArrayHasKey('fields', $map); + self::assertInternalType('array', $map['fields']); + self::assertCount(count($tableDescription), $map['fields']); + + foreach ($map['fields'] as $mappedName) { + self::assertContains('main_table.', $mappedName); + } + } +} From 4333c92bf37af3c9e50fd953a46e904f0a1c2b05 Mon Sep 17 00:00:00 2001 From: vtymchynskyi <vtymchynskyi@magento.com> Date: Tue, 2 Oct 2018 14:24:20 +0300 Subject: [PATCH 150/812] MAGETWO-95311: [2.3] Removed products are still exist in wishlist_item_option table in database --- .../Patch/Schema/AddProductIdConstraint.php | 79 +++++++++++++++++++ .../Wishlist/etc/db_schema_whitelist.json | 6 +- 2 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Wishlist/Setup/Patch/Schema/AddProductIdConstraint.php diff --git a/app/code/Magento/Wishlist/Setup/Patch/Schema/AddProductIdConstraint.php b/app/code/Magento/Wishlist/Setup/Patch/Schema/AddProductIdConstraint.php new file mode 100644 index 0000000000000..5c65fce10ccd2 --- /dev/null +++ b/app/code/Magento/Wishlist/Setup/Patch/Schema/AddProductIdConstraint.php @@ -0,0 +1,79 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Wishlist\Setup\Patch\Schema; + +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\Setup\Patch\SchemaPatchInterface; +use Magento\Framework\Setup\SchemaSetupInterface; + +/** + * Class AddProductIdConstraint + */ +class AddProductIdConstraint implements SchemaPatchInterface +{ + /** + * @var SchemaSetupInterface + */ + private $schemaSetup; + + /** + * @param SchemaSetupInterface $schemaSetup + */ + public function __construct( + SchemaSetupInterface $schemaSetup + ) { + $this->schemaSetup = $schemaSetup; + } + + /** + * Run code inside patch. + * + * @return void + */ + public function apply() + { + $this->schemaSetup->startSetup(); + + $this->schemaSetup->getConnection()->addForeignKey( + $this->schemaSetup->getConnection()->getForeignKeyName( + $this->schemaSetup->getTable('wishlist_item_option'), + 'product_id', + $this->schemaSetup->getTable('catalog_product_entity'), + 'entity_id' + ), + $this->schemaSetup->getTable('wishlist_item_option'), + 'product_id', + $this->schemaSetup->getTable('catalog_product_entity'), + 'entity_id', + AdapterInterface::FK_ACTION_CASCADE, + true + ); + + $this->schemaSetup->endSetup(); + } + + /** + * Get array of patches that have to be executed prior to this. + * + * @return string[] + */ + public static function getDependencies() + { + return []; + } + + /** + * Get aliases (previous names) for the patch. + * + * @return string[] + */ + public function getAliases() + { + return []; + } +} diff --git a/app/code/Magento/Wishlist/etc/db_schema_whitelist.json b/app/code/Magento/Wishlist/etc/db_schema_whitelist.json index beaab64280a76..36a294f26e145 100644 --- a/app/code/Magento/Wishlist/etc/db_schema_whitelist.json +++ b/app/code/Magento/Wishlist/etc/db_schema_whitelist.json @@ -35,8 +35,7 @@ "PRIMARY": true, "WISHLIST_ITEM_WISHLIST_ID_WISHLIST_WISHLIST_ID": true, "WISHLIST_ITEM_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID": true, - "WISHLIST_ITEM_STORE_ID_STORE_STORE_ID": true, - "WISHLIST_ITEM_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true + "WISHLIST_ITEM_STORE_ID_STORE_STORE_ID": true } }, "wishlist_item_option": { @@ -49,7 +48,8 @@ }, "constraint": { "PRIMARY": true, - "FK_A014B30B04B72DD0EAB3EECD779728D6": true + "FK_A014B30B04B72DD0EAB3EECD779728D6": true, + "WISHLIST_ITEM_OPTION_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID": true } } } \ No newline at end of file From 6db1a827593a6a2196f0c711256cd5bbfc507ae1 Mon Sep 17 00:00:00 2001 From: bshevchenko <1408sheva@gmail.com> Date: Tue, 2 Oct 2018 17:02:00 +0300 Subject: [PATCH 151/812] MAGETWO-95332: Update price in shopping cart after product save --- .../Mftf/Section/AdminMainActionsSection.xml | 4 +- .../Mftf/ActionGroup/CheckoutActionGroup.xml | 9 ++- .../Mftf/Section/CheckoutPaymentSection.xml | 7 +- .../Section/StorefrontMiniCartSection.xml | 1 + ...riceInShoppingCartAfterProductSaveTest.xml | 66 +++++++++++++++++++ .../AdminConfigCustomerActionGroup.xml | 20 ++++++ .../Mftf/Page/AdminCustomerConfigPage.xml | 12 ++++ .../Section/AdminCustomerConfigSection.xml | 12 ++++ 8 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminConfigCustomerActionGroup.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Page/AdminCustomerConfigPage.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerConfigSection.xml diff --git a/app/code/Magento/Backend/Test/Mftf/Section/AdminMainActionsSection.xml b/app/code/Magento/Backend/Test/Mftf/Section/AdminMainActionsSection.xml index cb164d43a49ff..bc576559e7a13 100644 --- a/app/code/Magento/Backend/Test/Mftf/Section/AdminMainActionsSection.xml +++ b/app/code/Magento/Backend/Test/Mftf/Section/AdminMainActionsSection.xml @@ -9,7 +9,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminMainActionsSection"> - <element name="save" type="button" selector="#save"/> - <element name="delete" type="button" selector="#delete"/> + <element name="save" type="button" selector="#save" timeout="30"/> + <element name="delete" type="button" selector="#delete" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index 32d6ad8667029..2e800cdb3fb8c 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -10,17 +10,16 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <!-- Go to checkout from minicart --> <actionGroup name="GoToCheckoutFromMinicartActionGroup"> - <wait stepKey="wait" time="10" /> + <waitForElementNotVisible selector="{{StorefrontMinicartSection.emptyCart}}" stepKey="waitUpdateQuantity" /> <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickCart"/> <click selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="goToCheckout"/> - <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> <!-- Guest checkout filling shipping section --> <actionGroup name="GuestCheckoutFillingShippingSectionActionGroup"> <arguments> - <argument name="customerVar"/> - <argument name="customerAddressVar"/> + <argument name="customerVar" defaultValue="CustomerEntityOne"/> + <argument name="customerAddressVar" defaultValue="CustomerAddressSimple"/> </arguments> <fillField selector="{{CheckoutShippingSection.email}}" userInput="{{customerVar.email}}" stepKey="enterEmail"/> <fillField selector="{{CheckoutShippingSection.firstName}}" userInput="{{customerVar.firstname}}" stepKey="enterFirstName"/> @@ -161,4 +160,4 @@ <see userInput="You are signed out" stepKey="signOut"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index 7dda1110fd145..2a6a6bb6d2593 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -25,7 +25,7 @@ <element name="billingAddress" type="text" selector="div.billing-address-details"/> <element name="cartItems" type="text" selector="ol.minicart-items"/> <element name="cartItemsArea" type="button" selector="div.block.items-in-cart"/> - <element name="cartItemsAreaActive" type="textarea" selector="div.block.items-in-cart.active"/> + <element name="cartItemsAreaActive" type="textarea" selector="div.block.items-in-cart.active" timeout="30"/> <element name="checkMoneyOrderPayment" type="radio" selector="input#checkmo.radio" timeout="30"/> <element name="placeOrder" type="button" selector="button.action.primary.checkout" timeout="30"/> <element name="paymentSectionTitle" type="text" selector="//*[@id='checkout-payment-method-load']//div[text()='Payment Method']" /> @@ -40,8 +40,9 @@ <element name="shipToInformation" type="text" selector="//div[@class='ship-to']//div[@class='shipping-information-content']" /> <element name="shippingMethodInformation" type="text" selector="//div[@class='ship-via']//div[@class='shipping-information-content']" /> <element name="paymentMethodTitle" type="text" selector=".payment-method-title span" /> - <element name="productOptionsByProductItemPrice" type="text" selector="//div[@class='product-item-inner']//div[@class='subtotal']//span[@class='price'][contains(.,'{{var1}}')]//ancestor::div[@class='product-item-details']//div[@class='product options']" parameterized="true"/> - <element name="productOptionsActiveByProductItemPrice" type="text" selector="//div[@class='subtotal']//span[@class='price'][contains(.,'{{var1}}')]//ancestor::div[@class='product-item-details']//div[@class='product options active']" parameterized="true"/> + <element name="productOptionsByProductItemPrice" type="text" selector="//div[@class='product-item-inner']//div[@class='subtotal']//span[@class='price'][contains(.,'{{price}}')]//ancestor::div[@class='product-item-details']//div[@class='product options']" parameterized="true"/> + <element name="productOptionsActiveByProductItemPrice" type="text" selector="//div[@class='subtotal']//span[@class='price'][contains(.,'{{price}}')]//ancestor::div[@class='product-item-details']//div[@class='product options active']" parameterized="true"/> + <element name="productItemPriceByName" type="text" selector="//div[@class='product-item-details'][contains(., '{{ProductName}}')]//span[@class='price']" parameterized="true"/> <element name="tax" type="text" selector="[data-th='Tax'] span" timeout="30"/> <element name="taxPercentage" type="text" selector=".totals-tax-details .mark"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml index c8ff851ae54ab..ccb626d4e1e41 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml @@ -27,5 +27,6 @@ <element name="itemQuantityUpdate" type="button" selector="//a[text()='{{productName}}']/../..//span[text()='Update']" parameterized="true"/> <element name="itemDiscount" type="text" selector="//tr[@class='totals']//td[@class='amount']/span"/> <element name="subtotal" type="text" selector="//tr[@class='totals sub']//td[@class='amount']/span"/> + <element name="emptyCart" type="text" selector=".counter.qty.empty"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml new file mode 100644 index 0000000000000..91f9cbf398d24 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml @@ -0,0 +1,66 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontUpdatePriceInShoppingCartAfterProductSaveTest"> + <annotations> + <features value="Checkout"/> + <stories value="Checkout via the Storefront"/> + <title value="Update price in shopping cart after product save"/> + <description value="Price in shopping cart should be updated after product save with changed price"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-58179"/> + <group value="checkout"/> + </annotations> + <before> + <createData entity="SimpleProduct2" stepKey="createSimpleProduct"> + <field key="price">100</field> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="SetCustomerDataLifetimeActionGroup" stepKey="setCustomerDataLifetime"> + <argument name="minutes" value="1"/> + </actionGroup> + </before> + <after> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> + <actionGroup ref="SetCustomerDataLifetimeActionGroup" stepKey="setDefaultCustomerDataLifetime"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Go to product page--> + <amOnPage url="{{StorefrontProductPage.url($$createSimpleProduct.custom_attributes[url_key]$$)}}" stepKey="navigateToSimpleProductPage"/> + + <!--Add Product to Shopping Cart--> + <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProductPage"> + <argument name="productName" value="$$createSimpleProduct.name$$"/> + </actionGroup> + + <!--Go to Checkout--> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart"/> + <actionGroup ref="GuestCheckoutFillingShippingSectionActionGroup" stepKey="guestCheckoutFillingShipping"/> + + <!--Check price--> + <conditionalClick selector="{{CheckoutPaymentSection.cartItemsArea}}" dependentSelector="{{CheckoutPaymentSection.cartItemsAreaActive}}" visible="false" stepKey="openItemProductBlock"/> + <see userInput="$100.00" selector="{{CheckoutPaymentSection.orderSummarySubtotal}}" stepKey="checkSummarySubtotal"/> + <see userInput="$100.00" selector="{{CheckoutPaymentSection.productItemPriceByName($$createSimpleProduct.name$$)}}" stepKey="checkItemPrice"/> + + <!--Edit product price via admin panel--> + <openNewTab stepKey="openNewTab"/> + <amOnPage url="{{AdminProductEditPage.url($$createSimpleProduct.id$$)}}" stepKey="goToProductEditPage"/> + <fillField userInput="120" selector="{{AdminProductFormSection.productPrice}}" stepKey="setNewPrice"/> + <actionGroup ref="saveProductForm" stepKey="saveProduct"/> + <closeTab stepKey="closeTab"/> + + <!--Check price--> + <reloadPage stepKey="reloadPage"/> + <waitForPageLoad stepKey="waitForCheckoutPageReload"/> + <conditionalClick selector="{{CheckoutPaymentSection.cartItemsArea}}" dependentSelector="{{CheckoutPaymentSection.cartItemsAreaActive}}" visible="false" stepKey="openItemProductBlock1"/> + <see userInput="$120.00" selector="{{CheckoutPaymentSection.orderSummarySubtotal}}" stepKey="checkSummarySubtotal1"/> + <see userInput="$120.00" selector="{{CheckoutPaymentSection.productItemPriceByName($$createSimpleProduct.name$$)}}" stepKey="checkItemPrice1"/> + </test> +</tests> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminConfigCustomerActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminConfigCustomerActionGroup.xml new file mode 100644 index 0000000000000..8a3ab7068696c --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminConfigCustomerActionGroup.xml @@ -0,0 +1,20 @@ +<?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="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="SetCustomerDataLifetimeActionGroup"> + <arguments> + <argument name="minutes" defaultValue="60" type="string"/> + </arguments> + <amOnPage url="{{AdminCustomerConfigPage.url('#customer_online_customers-link')}}" stepKey="openCustomerConfigPage"/> + <fillField userInput="{{minutes}}" selector="{{AdminCustomerConfigSection.customerDataLifetime}}" stepKey="fillCustomerDataLifetime"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSave"/> + <seeElement selector="{{AdminMessagesSection.success}}" stepKey="seeSuccessMessage"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/Page/AdminCustomerConfigPage.xml b/app/code/Magento/Customer/Test/Mftf/Page/AdminCustomerConfigPage.xml new file mode 100644 index 0000000000000..282f9bb6fdeb5 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Page/AdminCustomerConfigPage.xml @@ -0,0 +1,12 @@ +<?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="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="AdminCustomerConfigPage" url="admin/system_config/edit/section/customer/{{tabLink}}" area="admin" parameterized="true" module="Magento_Customer"> + <section name="AdminCustomerConfigSection"/> + </page> +</pages> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerConfigSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerConfigSection.xml new file mode 100644 index 0000000000000..9e104eb52cf90 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerConfigSection.xml @@ -0,0 +1,12 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminCustomerConfigSection"> + <element name="customerDataLifetime" type="input" selector="#customer_online_customers_section_data_lifetime"/> + </section> +</sections> From ac753fd7ec9d115726270038094f4b42fedfbaf0 Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Tue, 2 Oct 2018 17:04:12 +0300 Subject: [PATCH 152/812] MAGETWO-95312: [2.3] Cart is not empty after removing the product --- .../Magento/Checkout/Controller/Cart/Delete.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Controller/Cart/Delete.php b/app/code/Magento/Checkout/Controller/Cart/Delete.php index 7e88a484f9f6c..e9c15bd7f8cc1 100644 --- a/app/code/Magento/Checkout/Controller/Cart/Delete.php +++ b/app/code/Magento/Checkout/Controller/Cart/Delete.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -8,6 +7,11 @@ use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +/** + * Action Delete. + * + * Deletes item from cart. + */ class Delete extends \Magento\Checkout\Controller\Cart implements HttpPostActionInterface { /** @@ -24,7 +28,12 @@ public function execute() $id = (int)$this->getRequest()->getParam('id'); if ($id) { try { - $this->cart->removeItem($id)->save(); + $this->cart->removeItem($id); + // We should set Totals to be recollected once more because of Cart model as usually is loading + // before action executing and in case when triggerRecollect setted as true recollecting will + // executed and the flag will be true already. + $this->cart->getQuote()->setTotalsCollectedFlag(false); + $this->cart->save(); } catch (\Exception $e) { $this->messageManager->addErrorMessage(__('We can\'t remove the item.')); $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e); From 5f9a9901530d8023b6756a0a73a2a9c7a4c1ee35 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Tue, 28 Aug 2018 13:38:50 +0300 Subject: [PATCH 153/812] MAGETWO-91569: Special characters in CSV return error: General system exception happened - Added message to "Select File to Import" field in import form --- .../ImportExport/Block/Adminhtml/Import/Edit/Form.php | 5 ++++- .../CatalogImportExport/_files/product_export_data.php | 2 +- .../_files/product_export_data_special_chars.php | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php index 39d0d5c7feaee..8fd73e466083a 100644 --- a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php +++ b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php @@ -212,7 +212,10 @@ protected function _prepareForm() 'label' => __('Select File to Import'), 'title' => __('Select File to Import'), 'required' => true, - 'class' => 'input-file' + 'class' => 'input-file', + 'note' => __( + 'File must be saved in UTF-8 encoding for proper import' + ), ] ); $fieldsets['upload']->addField( diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php index 89fb9952cc6f1..477494626b9fb 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php @@ -70,7 +70,7 @@ )->setPrice( 10 )->addData( - ['text_attribute' => '!@#$%^&*()_+1234567890-=|\\:;"\'<,>.?/'] + ['text_attribute' => '!@#$%^&*()_+1234567890-=|\\:;"\'<,>.?/›ƒª'] )->setTierPrice( [0 => ['website_id' => 0, 'cust_group' => 0, 'price_qty' => 3, 'price' => 8]] )->setVisibility( diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars.php index a2c2c1815a8a9..591dccf229f89 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars.php @@ -25,7 +25,7 @@ ->setName('New Product') ->setSku('simple "1"') ->setPrice(10) - ->addData(['text_attribute' => '!@#$%^&*()_+1234567890-=|\\:;"\'<,>.?/']) + ->addData(['text_attribute' => '!@#$%^&*()_+1234567890-=|\\:;"\'<,>.?/›ƒª']) ->setTierPrice([0 => ['website_id' => 0, 'cust_group' => 0, 'price_qty' => 3, 'price' => 8]]) ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) From 7c5962a43c38024275530ba71215acdd9573bbb5 Mon Sep 17 00:00:00 2001 From: vprohorov <prohorov.vital@gmail.com> Date: Wed, 19 Sep 2018 02:57:08 +0300 Subject: [PATCH 154/812] MAGETWO-91684: Issue with Newsletter subscriptions - Changing subscription behavior to websites --- .../Model/ResourceModel/Subscriber.php | 43 ++++++++++--------- .../Magento/Newsletter/Model/Subscriber.php | 3 ++ 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php b/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php index b6e53b3695f78..100d179cbb60e 100644 --- a/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php @@ -5,6 +5,9 @@ */ namespace Magento\Newsletter\Model\ResourceModel; +use Magento\Framework\App\ObjectManager; +use Magento\Store\Model\StoreManagerInterface; + /** * Newsletter subscriber resource model * @@ -48,6 +51,11 @@ class Subscriber extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ protected $mathRandom; + /** + * @var StoreManagerInterface + */ + private $storeManager; + /** * Construct * @@ -55,15 +63,18 @@ class Subscriber extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb * @param \Magento\Framework\Stdlib\DateTime\DateTime $date * @param \Magento\Framework\Math\Random $mathRandom * @param string $connectionName + * @param StoreManagerInterface $storeManager */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, \Magento\Framework\Stdlib\DateTime\DateTime $date, \Magento\Framework\Math\Random $mathRandom, - $connectionName = null + $connectionName = null, + StoreManagerInterface $storeManager = null ) { $this->_date = $date; $this->mathRandom = $mathRandom; + $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class); parent::__construct($context, $connectionName); } @@ -117,19 +128,15 @@ public function loadByEmail($subscriberEmail) */ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface $customer) { + $storeIds = $this->storeManager->getWebsite($customer->getWebsiteId())->getStoreIds(); + $select = $this->connection ->select() ->from($this->getMainTable()) - ->where('customer_id=:customer_id and store_id=:store_id'); - - $result = $this->connection - ->fetchRow( - $select, - [ - 'customer_id' => $customer->getId(), - 'store_id' => $customer->getStoreId() - ] - ); + ->where('customer_id = ?', $customer->getId()) + ->where('store_id IN (?)', $storeIds); + + $result = $this->connection->fetchRow($select); if ($result) { return $result; @@ -138,16 +145,10 @@ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface $select = $this->connection ->select() ->from($this->getMainTable()) - ->where('subscriber_email=:subscriber_email and store_id=:store_id'); - - $result = $this->connection - ->fetchRow( - $select, - [ - 'subscriber_email' => $customer->getEmail(), - 'store_id' => $customer->getStoreId() - ] - ); + ->where('subscriber_email = ?', $customer->getEmail()) + ->where('store_id IN (?)', $storeIds); + + $result = $this->connection->fetchRow($select); if ($result) { return $result; diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php index 03976dfcdc197..9611e4b67f1e2 100644 --- a/app/code/Magento/Newsletter/Model/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/Subscriber.php @@ -392,6 +392,9 @@ public function loadByCustomerId($customerId) try { $customerData = $this->customerRepository->getById($customerId); $customerData->setStoreId($this->_storeManager->getStore()->getId()); + if ($customerData->getWebsiteId() === null) { + $customerData->setWebsiteId($this->_storeManager->getStore()->getWebsiteId()); + } $data = $this->getResource()->loadByCustomerData($customerData); $this->addData($data); if (!empty($data) && $customerData->getId() && !$this->getCustomerId()) { From 9ff3f48412067730c9926bf6354d896d4b21f4a8 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 3 Oct 2018 13:47:29 +0300 Subject: [PATCH 155/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Magento/Backend/Block/Media/Uploader.php | 26 +++++-- .../Backend/Model/Image/ImageUploadConfig.php | 72 +++++++++++++++++++ .../Image/ImageUploadConfigInterface.php | 37 ++++++++++ app/code/Magento/Backend/etc/adminhtml/di.xml | 1 + .../Magento/Backend/etc/adminhtml/system.xml | 15 +++- app/code/Magento/Backend/etc/config.xml | 1 + .../adminhtml/templates/media/uploader.phtml | 3 +- .../view/adminhtml/web/js/media-uploader.js | 16 +++-- .../Magento/Framework/File/Uploader.php | 4 +- .../Framework/Image/Adapter/Config.php | 12 ++++ .../Image/Adapter/UploadConfigInterface.php | 2 + 11 files changed, 173 insertions(+), 16 deletions(-) create mode 100644 app/code/Magento/Backend/Model/Image/ImageUploadConfig.php create mode 100644 app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php index eb98808dd644b..6962141c465b8 100644 --- a/app/code/Magento/Backend/Block/Media/Uploader.php +++ b/app/code/Magento/Backend/Block/Media/Uploader.php @@ -10,6 +10,7 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\Image\Adapter\UploadConfigInterface; +use Magento\Backend\Model\Image\ImageUploadConfigInterface; /** * Adminhtml media library uploader @@ -39,9 +40,9 @@ class Uploader extends \Magento\Backend\Block\Widget private $jsonEncoder; /** - * @var UploadConfigInterface + * @var ImageUploadConfigInterface */ - private $imageConfig; + private $imageUploadConfig; /** * @param \Magento\Backend\Block\Template\Context $context @@ -49,18 +50,19 @@ class Uploader extends \Magento\Backend\Block\Widget * @param array $data * @param Json $jsonEncoder * @param UploadConfigInterface $imageConfig + * @param ImageUploadConfigInterface $imageUploadConfig */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Framework\File\Size $fileSize, array $data = [], Json $jsonEncoder = null, - UploadConfigInterface $imageConfig = null + UploadConfigInterface $imageConfig = null, + ImageUploadConfigInterface $imageUploadConfig = null ) { $this->_fileSizeService = $fileSize; $this->jsonEncoder = $jsonEncoder ?: ObjectManager::getInstance()->get(Json::class); - $this->imageConfig = $imageConfig ?: ObjectManager::getInstance()->get(UploadConfigInterface::class); - + $this->imageUploadConfig = $imageUploadConfig ?: ObjectManager::getInstance()->get(UploadConfigInterface::class); parent::__construct($context, $data); } @@ -111,7 +113,7 @@ public function getFileSizeService() */ public function getImageUploadMaxWidth() { - return $this->imageConfig->getMaxWidth(); + return $this->imageUploadConfig->getMaxWidth(); } /** @@ -121,7 +123,17 @@ public function getImageUploadMaxWidth() */ public function getImageUploadMaxHeight() { - return $this->imageConfig->getMaxHeight(); + return $this->imageUploadConfig->getMaxHeight(); + } + + /** + * Get image resize configuration + * + * @return bool + */ + public function getIsResizeEnabled(): bool + { + return $this->imageUploadConfig->isResizeEnabled(); } /** diff --git a/app/code/Magento/Backend/Model/Image/ImageUploadConfig.php b/app/code/Magento/Backend/Model/Image/ImageUploadConfig.php new file mode 100644 index 0000000000000..b7e13b1e8274c --- /dev/null +++ b/app/code/Magento/Backend/Model/Image/ImageUploadConfig.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Backend\Model\Image; + +/** + * Image uploader config provider. + */ +class ImageUploadConfig implements ImageUploadConfigInterface +{ + /** + * Config path for the maximal image width value + */ + const XML_PATH_MAX_WIDTH_IMAGE = 'system/upload_configuration/max_width'; + + /** + * Config path for the maximal image height value + */ + const XML_PATH_MAX_HEIGHT_IMAGE = 'system/upload_configuration/max_height'; + + /** + * Config path for the maximal image height value + */ + const XML_PATH_ENABLE_RESIZE = 'system/upload_configuration/enable_resize'; + + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface + */ + private $config; + + /** + * @param \Magento\Framework\App\Config\ScopeConfigInterface $config + */ + public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $config) + { + $this->config = $config; + } + + /** + * Get maximal width value for resized image + * + * @return int + */ + public function getMaxWidth(): int + { + return (int)$this->config->getValue(self::XML_PATH_MAX_WIDTH_IMAGE); + } + + /** + * Get maximal height value for resized image + * + * @return int + */ + public function getMaxHeight(): int + { + return (int)$this->config->getValue(self::XML_PATH_MAX_HEIGHT_IMAGE); + } + + /** + * Get config value for frontend resize + * + * @return bool + */ + public function isResizeEnabled(): bool + { + return (bool)$this->config->getValue(self::XML_PATH_ENABLE_RESIZE); + } +} diff --git a/app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php b/app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php new file mode 100644 index 0000000000000..254a13407b2c1 --- /dev/null +++ b/app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Backend\Model\Image; + +/** + * Interface ImageUploadConfigInterface + * + * Used to retrieve configuration for frontend image uploader + */ +interface ImageUploadConfigInterface +{ + /** + * Get maximal width value for resized image + * + * @return int + */ + public function getMaxWidth(): int; + + /** + * Get maximal height value for resized image + * + * @return int + */ + public function getMaxHeight(): int; + + /** + * Get config value for frontend resize + * + * @return bool + */ + public function isResizeEnabled(): bool; +} diff --git a/app/code/Magento/Backend/etc/adminhtml/di.xml b/app/code/Magento/Backend/etc/adminhtml/di.xml index 3384384343fe9..dcfc99cfed310 100644 --- a/app/code/Magento/Backend/etc/adminhtml/di.xml +++ b/app/code/Magento/Backend/etc/adminhtml/di.xml @@ -168,4 +168,5 @@ </arguments> </type> <preference for="CsrfRequestValidator" type="Magento\Backend\App\Request\BackendValidator" /> + <preference for="Magento\Backend\Model\Image\ImageUploadConfigInterface" type="Magento\Backend\Model\Image\ImageUploadConfig" /> </config> diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index e061455acbe6b..3a0d3e50acc5a 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -338,15 +338,26 @@ </group> <group id="upload_configuration" translate="label" type="text" sortOrder="1000" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Images Upload Configuration</label> - <field id="max_width" translate="label comment" type="text" sortOrder="100" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> + <field id="enable_resize" translate="label" type="select" sortOrder="200" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> + <label>Enable Front-end Resize</label> + <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + <comment>Resize performed by javascript during file upload.</comment> + </field> + <field id="max_width" translate="label comment" type="text" sortOrder="300" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Maximum Width</label> <validate>validate-greater-than-zero validate-number required-entry</validate> <comment>Maximum allowed width for uploaded image.</comment> + <depends> + <field id="enable_resize">1</field> + </depends> </field> - <field id="max_height" translate="label comment" type="text" sortOrder="200" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> + <field id="max_height" translate="label comment" type="text" sortOrder="400" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Maximum Height</label> <validate>validate-greater-than-zero validate-number required-entry</validate> <comment>Maximum allowed height for uploaded image.</comment> + <depends> + <field id="enable_resize">1</field> + </depends> </field> </group> </section> diff --git a/app/code/Magento/Backend/etc/config.xml b/app/code/Magento/Backend/etc/config.xml index 45d283ad3ff22..8283fa18dd370 100644 --- a/app/code/Magento/Backend/etc/config.xml +++ b/app/code/Magento/Backend/etc/config.xml @@ -29,6 +29,7 @@ <enable_charts>1</enable_charts> </dashboard> <upload_configuration> + <enable_resize>1</enable_resize> <max_width>1920</max_width> <max_height>1200</max_height> </upload_configuration> diff --git a/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml b/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml index 966372773f295..edd54ae38b6a1 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml @@ -14,7 +14,8 @@ "Magento_Backend/js/media-uploader" : { "maxFileSize": <?= /* @escapeNotVerified */ $block->getFileSizeService()->getMaxFileSize() ?>, "maxWidth":<?= /* @escapeNotVerified */ $block->getImageUploadMaxWidth() ?> , - "maxHeight": <?= /* @escapeNotVerified */ $block->getImageUploadMaxHeight() ?> + "maxHeight": <?= /* @escapeNotVerified */ $block->getImageUploadMaxHeight() ?>, + "isResizeEnabled": <?= /* @noEscape */ $block->getIsResizeEnabled() ?> } }' > diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js index 7e0b6bdfb46dd..35e9ec244df24 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js +++ b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js @@ -35,7 +35,10 @@ define([ _create: function () { var self = this, - progressTmpl = mageTemplate('[data-template="uploader"]'); + progressTmpl = mageTemplate('[data-template="uploader"]'), + resizeConfig = { + action: 'resize' + }; this.element.find('input[type=file]').fileupload({ dataType: 'json', @@ -120,14 +123,19 @@ define([ stop: fileUploader.uploaderConfig.stop }); + if (typeof this.options.isResizeEnabled !== 'undefined' && this.options.isResizeEnabled === true) { + resizeConfig.maxWidth = this.options.maxWidth; + resizeConfig.maxHeight = this.options.maxHeight; + } + this.element.find('input[type=file]').fileupload('option', { process: [{ action: 'load', fileTypes: /^image\/(gif|jpeg|png)$/, maxFileSize: this.options.maxFileSize - }, { - action: 'resize' - }, { + }, + resizeConfig, + { action: 'save' }] }); diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index 9a6787ddbaffd..0785177042451 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -140,14 +140,14 @@ class Uploader * @deprecated * @see \Magento\Framework\Image\Adapter\UploadConfigInterface::getMaxWidth() */ - const MAX_IMAGE_WIDTH = 4096; + const MAX_IMAGE_WIDTH = 1920; /** * Maximum Image Height resolution in pixels. For image resizing on client side * @deprecated * @see \Magento\Framework\Image\Adapter\UploadConfigInterface::getMaxHeight() */ - const MAX_IMAGE_HEIGHT = 2160; + const MAX_IMAGE_HEIGHT = 1200; /** * Resulting of uploaded file diff --git a/lib/internal/Magento/Framework/Image/Adapter/Config.php b/lib/internal/Magento/Framework/Image/Adapter/Config.php index a159bc9ffd448..84b6b6dcfbdd1 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Config.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Config.php @@ -16,8 +16,16 @@ class Config implements ConfigInterface, UploadConfigInterface const XML_PATH_IMAGE_ADAPTERS = 'dev/image/adapters'; + /** + * Config path for the maximal image width value + * @deprecated + */ const XML_PATH_MAX_WIDTH_IMAGE = 'system/upload_configuration/max_width'; + /** + * Config path for the maximal image height value + * @deprecated + */ const XML_PATH_MAX_HEIGHT_IMAGE = 'system/upload_configuration/max_height'; /** @@ -57,6 +65,8 @@ public function getAdapters() * Get Maximum Image Width resolution in pixels. For image resizing on client side. * * @return int + * @deprecated + * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface::getMaxHeight() */ public function getMaxWidth(): int { @@ -67,6 +77,8 @@ public function getMaxWidth(): int * Get Maximum Image Height resolution in pixels. For image resizing on client side. * * @return int + * @deprecated + * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface::getMaxHeight() */ public function getMaxHeight(): int { diff --git a/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php b/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php index c42879060b0b2..990062b83ef6f 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php +++ b/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php @@ -9,6 +9,8 @@ /** * Interface UploadConfigInterface + * @deprecated because new interface was introduced + * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface; */ interface UploadConfigInterface { From e5a30aab22728751c8a79a1d0062f4e2206766e4 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 3 Oct 2018 14:32:22 +0300 Subject: [PATCH 156/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- app/code/Magento/Backend/Block/Media/Uploader.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php index 6962141c465b8..1995d72661e2e 100644 --- a/app/code/Magento/Backend/Block/Media/Uploader.php +++ b/app/code/Magento/Backend/Block/Media/Uploader.php @@ -62,7 +62,8 @@ public function __construct( ) { $this->_fileSizeService = $fileSize; $this->jsonEncoder = $jsonEncoder ?: ObjectManager::getInstance()->get(Json::class); - $this->imageUploadConfig = $imageUploadConfig ?: ObjectManager::getInstance()->get(UploadConfigInterface::class); + $this->imageUploadConfig = $imageUploadConfig + ?: ObjectManager::getInstance()->get(ImageUploadConfigInterface::class); parent::__construct($context, $data); } From 7547dd2e0a66d66fc0ed1b4dcb2ccd9de792a6b4 Mon Sep 17 00:00:00 2001 From: Oksana_Kremen <Oksana_Kremen@epam.com> Date: Wed, 3 Oct 2018 15:38:50 +0300 Subject: [PATCH 157/812] MAGETWO-91750: Multiselect attribute values is not searchable under Quick Search when more than one value is selected - Added possibility to retrieve multiselect option values for catalog fulltext search reindexation --- .../Indexer/Fulltext/Action/DataProvider.php | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) 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 83058b6f0ad55..3882921680a42 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -12,6 +12,8 @@ use Magento\Store\Model\Store; /** + * Data provider class + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) * @api @@ -570,8 +572,8 @@ public function prepareProductIndex($indexData, $productData, $storeId) } } foreach ($indexData as $entityId => $attributeData) { - foreach ($attributeData as $attributeId => $attributeValue) { - $value = $this->getAttributeValue($attributeId, $attributeValue, $storeId); + foreach ($attributeData as $attributeId => $attributeValues) { + $value = $this->getAttributeValue($attributeId, $attributeValues, $storeId); if (!empty($value)) { if (isset($index[$attributeId])) { $index[$attributeId][$entityId] = $value; @@ -602,16 +604,16 @@ public function prepareProductIndex($indexData, $productData, $storeId) * Retrieve attribute source value for search * * @param int $attributeId - * @param mixed $valueId + * @param mixed $valueIds * @param int $storeId * @return string */ - private function getAttributeValue($attributeId, $valueId, $storeId) + private function getAttributeValue($attributeId, $valueIds, $storeId) { $attribute = $this->getSearchableAttribute($attributeId); - $value = $this->engine->processAttributeValue($attribute, $valueId); + $value = $this->engine->processAttributeValue($attribute, $valueIds); if (false !== $value) { - $optionValue = $this->getAttributeOptionValue($attributeId, $valueId, $storeId); + $optionValue = $this->getAttributeOptionValue($attributeId, $valueIds, $storeId); if (null === $optionValue) { $value = $this->filterAttributeValue($value); } else { @@ -626,13 +628,15 @@ private function getAttributeValue($attributeId, $valueId, $storeId) * Get attribute option value * * @param int $attributeId - * @param int $valueId + * @param int|string $valueIds * @param int $storeId * @return null|string */ - private function getAttributeOptionValue($attributeId, $valueId, $storeId) + private function getAttributeOptionValue($attributeId, $valueIds, $storeId) { $optionKey = $attributeId . '-' . $storeId; + $attributeValueIds = explode(',', $valueIds); + $attributeOptionValue = ''; if (!array_key_exists($optionKey, $this->attributeOptions) ) { $attribute = $this->getSearchableAttribute($attributeId); @@ -650,8 +654,10 @@ private function getAttributeOptionValue($attributeId, $valueId, $storeId) $this->attributeOptions[$optionKey] = null; } } - - return $this->attributeOptions[$optionKey][$valueId] ?? null; + foreach ($attributeValueIds as $attrValueId) { + $attributeOptionValue .= $this->attributeOptions[$optionKey][$attrValueId] . ' '; + } + return empty($attributeOptionValue) ? null : trim($attributeOptionValue); } /** From 94ce40832e4c405f22a748ff8445c1b5777589a1 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Wed, 3 Oct 2018 17:44:23 +0300 Subject: [PATCH 158/812] MAGETWO-91649: #13513: Magento ignore store-level url_key of child category in URL rewrite process for global scope - Fixed codestyle issue in 'ChildrenUrlRewriteGenerator'; --- .../Model/Category/ChildrenUrlRewriteGenerator.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php index f6049bbff02c4..d18034220cfa8 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/ChildrenUrlRewriteGenerator.php @@ -71,7 +71,8 @@ public function __construct( public function generate($storeId, Category $category, $rootCategoryId = null) { $mergeDataProvider = clone $this->mergeDataProviderPrototype; - if ($childrenIds = $this->childrenCategoriesProvider->getChildrenIds($category, true)) { + $childrenIds = $this->childrenCategoriesProvider->getChildrenIds($category, true); + if ($childrenIds) { foreach ($childrenIds as $childId) { /** @var Category $childCategory */ $childCategory = $this->categoryRepository->get($childId, $storeId); From b1b39283c17b718a356f8f16e39815885e096637 Mon Sep 17 00:00:00 2001 From: stefank <stefan.koch@adyen.com> Date: Wed, 3 Oct 2018 17:04:51 +0200 Subject: [PATCH 159/812] Support of error pages behind a load balancer that serves HTTPS but accesses the webserver on HTTP. Without this css is loaded on HTTP from a document loaded over HTTPS --- pub/errors/processor.php | 1 - 1 file changed, 1 deletion(-) diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 6add4e8cb3ad1..8756aab1acec3 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -265,7 +265,6 @@ public function getHostUrl() $host = 'localhost'; } - // HTTP_X_FORWARDED_PROTO to check whether a webserver using HTTP is behind a load balancer serving HTTPS $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off') || $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'; $url = ($isSecure ? 'https://' : 'http://') . $host; From 53452fbe0dbe96e1ceb3f91973fc88e25c9108ee Mon Sep 17 00:00:00 2001 From: stefank <stefan.koch@adyen.com> Date: Wed, 3 Oct 2018 17:15:43 +0200 Subject: [PATCH 160/812] Support of error pages behind a load balancer that serves HTTPS but accesses the webserver on HTTP. Without this css is loaded on HTTP from a document loaded over HTTPS --- pub/errors/processor.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 8756aab1acec3..3958c6d152c9d 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -265,7 +265,8 @@ public function getHostUrl() $host = 'localhost'; } - $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off') || $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'; + $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off') + || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'); $url = ($isSecure ? 'https://' : 'http://') . $host; if (!empty($_SERVER['SERVER_PORT']) && !in_array($_SERVER['SERVER_PORT'], [80, 443]) From 24672336afc2a748ab6f221a534f93ff1e894fdd Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Wed, 3 Oct 2018 18:00:18 +0200 Subject: [PATCH 161/812] Concept for setting shipping method only for single address checkout --- .../SetShippingMethodsOnCart.php | 111 +++++++++++------- .../Magento/QuoteGraphQl/etc/schema.graphqls | 5 +- 2 files changed, 71 insertions(+), 45 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php index 448bdcbb37a6d..f2e1be3bb0508 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php @@ -7,44 +7,63 @@ namespace Magento\QuoteGraphQl\Model\Resolver\ShippingMethod; +use Magento\Framework\Exception\CouldNotSaveException; +use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Exception\StateException; +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\Stdlib\ArrayManager; -use Magento\Quote\Api\CartRepositoryInterface; -use Magento\Quote\Api\Data\CartInterface; use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; +use Magento\Quote\Model\ShippingMethodManagementInterface; +use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser; +/** + * Class SetShippingMethodsOnCart + * + * Mutation resolver for setting shipping methods for shopping cart + */ class SetShippingMethodsOnCart implements ResolverInterface { - /** - * @var CartRepositoryInterface - */ - private $cartRepository; - /** * @var MaskedQuoteIdToQuoteIdInterface */ private $maskedQuoteIdToQuoteId; - /** * @var ArrayManager */ private $arrayManager; + /** + * @var ShippingMethodManagementInterface + */ + private $shippingMethodManagement; + + /** + * @var IsCartMutationAllowedForCurrentUser + */ + private $isCartMutationAllowedForCurrentUser; + /** * SetShippingMethodsOnCart constructor. * @param ArrayManager $arrayManager * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + * @param ShippingMethodManagementInterface $shippingMethodManagement */ public function __construct( ArrayManager $arrayManager, MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, - CartRepositoryInterface $cartRepository + ShippingMethodManagementInterface $shippingMethodManagement, + IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser ) { $this->arrayManager = $arrayManager; $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->cartRepository = $cartRepository; + $this->shippingMethodManagement = $shippingMethodManagement; + $this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser; } /** @@ -56,50 +75,56 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $maskedCartId = $this->arrayManager->get('input/cart_id', $args); if (!$maskedCartId) { - // TODO: throw an exception + throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); } if (!$shippingMethods) { - // TODO: throw an exception? + throw new GraphQlInputException(__('Required parameter "shipping_methods" is missing')); } - foreach ($shippingMethods as $shippingMethod) { - if (empty($shippingMethod['cart_address_id'])) { - // TODO: throw input exception - } - - if (empty($shippingMethod['shipping_method_code'])) { - // TODO: throw input exception - } + $shippingMethod = reset($shippingMethods); // TODO: provide implementation for multishipping - // TODO: move to a separate class - // TODO: check current customer can apply operations on specified cart + if (!$shippingMethod['shipping_carrier_code']) { // FIXME: check the E_WARNING here + throw new GraphQlInputException(__('Required parameter "shipping_carrier_code" is missing')); } - $quoteId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); - $quote = $this->cartRepository->get($quoteId); // TODO: catch no such entity exception - $this->setShippingMethods($shippingMethods, $quote); + if (!$shippingMethod['shipping_method_code']) { // FIXME: check the E_WARNING here + throw new GraphQlInputException(__('Required parameter "shipping_method_code" is missing')); + } - $quote->collectTotals(); - $quote->save(); - //$this->cartRepository->save($quote); + try { + $cartId = $this->maskedQuoteIdToQuoteId->execute((string) $maskedCartId); + } catch (NoSuchEntityException $exception) { + throw new GraphQlNoSuchEntityException( + __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $maskedCartId]) + ); + } - return 'Success!'; - } + if (false === $this->isCartMutationAllowedForCurrentUser->execute($cartId)) { + throw new GraphQlAuthorizationException( + __( + 'The current user cannot perform operations on cart "%masked_cart_id"', + ['masked_cart_id' => $maskedCartId] + ) + ); + } - private function setShippingMethods($shippingMethods, CartInterface $quote) - { - $addresses = $quote->getAllShippingAddresses(); - /** @var \Magento\Quote\Model\Quote\Address $address */ - foreach ($addresses as $address) { - $addressId = $address->getId(); - $shippingMethodForAddress = array_search($addressId, array_column($shippingMethods, 'cart_address_id')); - if ($shippingMethodForAddress !== false) { - $address->setShippingMethod($shippingMethods[$shippingMethodForAddress]['shipping_method_code']); -// $address->setCollectShippingRates(1); - $address->save(); - } + try { + $this->shippingMethodManagement->set( + $cartId, + $shippingMethods['shipping_carrier_code'], + $shippingMethods['shipping_method_code'] + ); + } catch (InputException $exception) { + throw new GraphQlInputException(__($exception->getMessage())); + } catch (CouldNotSaveException $exception) { + throw new GraphQlInputException(__($exception->getMessage())); + } catch (StateException $exception) { + throw new GraphQlInputException(__($exception->getMessage())); + } catch (NoSuchEntityException $exception) { + throw new GraphQlNoSuchEntityException(__($exception->getMessage())); } - // TODO: make sure that shipping method is assigned for all addresses + + return 'Success!'; // TODO we should return cart here } } \ No newline at end of file diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 8ecb340db691b..45f98daeaed06 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -53,7 +53,8 @@ input SetShippingMethodsOnCartInput { } input ShippingMethodForAddressInput { - cart_address_id: String! # todo: int? + cart_address_id: int + shipping_carrier_code: String! shipping_method_code: String! } @@ -66,7 +67,7 @@ type SetShippingAddressesOnCartOutput { } type SetShippingMethodsOnCartOutput { - cart: String + cart: String #TODO: temp placeholder, should be Cart! } # If no address is provided, the system get address assigned to a quote From ce0cb8c76c31545d3527243cbef1bd77947caf49 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Thu, 4 Oct 2018 13:39:59 +0300 Subject: [PATCH 162/812] MAGETWO-67269: Gift Options set to no still show up as choices on front end order page - Fix statics. --- app/code/Magento/GiftMessage/Block/Message/Inline.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/GiftMessage/Block/Message/Inline.php b/app/code/Magento/GiftMessage/Block/Message/Inline.php index f44f967cefdc6..4a9311c1b4ba2 100644 --- a/app/code/Magento/GiftMessage/Block/Message/Inline.php +++ b/app/code/Magento/GiftMessage/Block/Message/Inline.php @@ -139,7 +139,7 @@ public function getType() /** * Define checkout type * - * @param $type string + * @param string $type * @return $this * @codeCoverageIgnore */ @@ -278,6 +278,8 @@ public function countItems() } /** + * Call method getItemsHasMessages + * * @deprecated Misspelled method * @see getItemsHasMessages */ From ef8f126056b004cea86c5ce726794844e969f848 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Thu, 4 Oct 2018 15:15:11 +0300 Subject: [PATCH 163/812] graph-ql: concept of shipping address coverage, added separate flows for multi shipping and single shipping --- .../MultiShipping.php | 23 ++++ .../SingleShipping.php | 63 ++++++++++ .../SetShippingAddressesOnCart.php | 109 ++++++++++++------ 3 files changed, 162 insertions(+), 33 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php new file mode 100644 index 0000000000000..71560a26c03ee --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php @@ -0,0 +1,23 @@ +<?php +/** + * @author Atwix Team + * @copyright Copyright (c) 2018 Atwix (https://www.atwix.com/) + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart; + +class MultiShipping +{ + /** + * @param int $cartId + * @param array $cartItems + * @param int|null $customerAddressId + * @param array|null $address + * @return void + */ + public function setAddress(int $cartId, array $cartItems, ?int $customerAddressId, ?array $address): void + { + //TODO: implement multi shipping + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php new file mode 100644 index 0000000000000..536a907541b1a --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php @@ -0,0 +1,63 @@ +<?php +/** + * @author Atwix Team + * @copyright Copyright (c) 2018 Atwix (https://www.atwix.com/) + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart; + +use Magento\Quote\Model\Quote\Address; +use Magento\Quote\Model\ShippingAddressManagementInterface; +use Magento\Customer\Api\AddressRepositoryInterface; + +class SingleShipping +{ + /** + * @var ShippingAddressManagementInterface + */ + private $shippingAddressManagement; + + /** + * @var AddressRepositoryInterface + */ + private $addressRepository; + + /** + * @var Address + */ + private $addressModel; + + /** + * @param ShippingAddressManagementInterface $shippingAddressManagement + * @param AddressRepositoryInterface $addressRepository + * @param Address $addressModel + */ + public function __construct( + ShippingAddressManagementInterface $shippingAddressManagement, + AddressRepositoryInterface $addressRepository, + Address $addressModel + ) { + $this->shippingAddressManagement = $shippingAddressManagement; + $this->addressRepository = $addressRepository; + $this->addressModel = $addressModel; + } + + /** + * @param int $cartId + * @param int|null $customerAddressId + * @param array|null $address + * @return void + */ + public function setAddress(int $cartId, ?int $customerAddressId, ?array $address): void + { + if($customerAddressId) { + $customerAddress = $this->addressRepository->getById($customerAddressId); + $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); + } else { + $shippingAddress = $this->addressModel->addData($address); + } + + $this->shippingAddressManagement->assign($cartId, $shippingAddress); + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php index 9d54792136367..f3960f66d2792 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php @@ -7,15 +7,15 @@ namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress; -use Magento\Customer\Api\AddressRepositoryInterface; use Magento\Framework\Api\DataObjectHelper; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; -use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\ShippingAddressManagementInterface; +use Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\MultiShipping; +use Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\SingleShipping; /** * @inheritdoc @@ -23,48 +23,49 @@ class SetShippingAddressesOnCart implements ResolverInterface { /** - * @var ShippingAddressManagementInterface + * @var DataObjectHelper */ - private $shippingAddressManagement; + private $dataObjectHelper; /** - * @var AddressRepositoryInterface + * @var MaskedQuoteIdToQuoteIdInterface */ - private $addressRepository; + private $maskedQuoteIdToQuoteId; /** - * @var Address + * @var MultiShipping */ - private $addressModel; + private $multiShipping; + /** - * @var DataObjectHelper + * @var SingleShipping */ - private $dataObjectHelper; + private $singleShipping; /** - * @var MaskedQuoteIdToQuoteIdInterface + * @var ShippingAddressManagementInterface */ - private $maskedQuoteIdToQuoteId; + private $shippingAddressManagement; /** - * @param ShippingAddressManagementInterface $shippingAddressManagement - * @param AddressRepositoryInterface $addressRepository - * @param Address $addressModel * @param DataObjectHelper $dataObjectHelper * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + * @param MultiShipping $multiShipping + * @param SingleShipping $singleShipping + * @param ShippingAddressManagementInterface $shippingAddressManagement */ public function __construct( - ShippingAddressManagementInterface $shippingAddressManagement, - AddressRepositoryInterface $addressRepository, - Address $addressModel, DataObjectHelper $dataObjectHelper, - MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, + MultiShipping $multiShipping, + SingleShipping $singleShipping, + ShippingAddressManagementInterface $shippingAddressManagement ) { - $this->shippingAddressManagement = $shippingAddressManagement; - $this->addressRepository = $addressRepository; - $this->addressModel = $addressModel; $this->dataObjectHelper = $dataObjectHelper; $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; + $this->multiShipping = $multiShipping; + $this->singleShipping = $singleShipping; + $this->shippingAddressManagement = $shippingAddressManagement; } /** @@ -78,7 +79,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $maskedCartId = $args['input']['cart_id']; $cartId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); - $customerAddressId = $args['input']['customer_address_id'] ?? 0; + $customerAddressId = $args['input']['customer_address_id'] ?? null; $address = $args['input']['address'] ?? null; $cartItems = $args['input']['cart_items'] ?? []; @@ -86,19 +87,61 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value throw new GraphQlInputException(__('Query should contain either address id or address input.')); } + //TODO: how to determine whether is multi shipping or not if (!$cartItems) { - if($customerAddressId) { - $customerAddress = $this->addressRepository->getById($customerAddressId); - $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); - $this->shippingAddressManagement->assign($cartId, $shippingAddress); - } else { - $shippingAddress = $this->addressModel->addData($address); - $this->shippingAddressManagement->assign($cartId, $shippingAddress); - } + //TODO: assign cart items + $this->singleShipping->setAddress($cartId, $customerAddressId, $address); } else { - //TODO: implement multi shipping address assign flow + $this->multiShipping->setAddress($cartId, $cartItems, $customerAddressId, $address); } - return []; + //TODO: implement Cart object in the separate resolver + $shippingAddress = $this->shippingAddressManagement->get($cartId); + return [ + 'cart' => [ + 'applied_coupon' => [ + 'code' => '' + ], + 'addresses' => [[ + 'firstname' => $shippingAddress->getFirstname(), + 'lastname' => $shippingAddress->getLastname(), + 'company' => $shippingAddress->getCompany(), + 'street' => $shippingAddress->getStreet(), + 'city' => $shippingAddress->getCity(), + 'region' => [ + 'code' => $shippingAddress->getRegionCode(), + 'label' => $shippingAddress->getRegion() + ], + 'country' => [ + 'code' => $shippingAddress->getCountryId(), + 'label' => '' + ], + 'postcode' => $shippingAddress->getPostcode(), + 'telephone' => $shippingAddress->getTelephone(), + 'address_type' => 'SHIPPING', + 'selected_shipping_method' => [ + 'code' => 'test', + 'label' => 'test', + 'free_shipping' => 'test', + 'error_message' => 'test' + ], + 'available_shipping_methods' => [[ + 'code' => 'test', + 'label' => 'test', + 'free_shipping' => 'test', + 'error_message' => 'test' + ]], + 'items_weight' => [0], + 'customer_notes' => $shippingAddress->getLastname(), + 'cart_items' => [[ + 'cart_item_id' => '', + 'quantity' => 0 + ]], + 'applied_coupon' => [ + 'code' => '' + ] + ]] + ] + ]; } } From e7c2ddcfbfa9668c0a7d8c8706892740add84c5d Mon Sep 17 00:00:00 2001 From: Yurii Borysov <yurii_borysov@epam.com> Date: Thu, 4 Oct 2018 16:12:11 +0300 Subject: [PATCH 164/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix elements arrangement issue --- .../adminhtml/web/css/grouped-product.css | 13 +++++-- .../adminhtml/web/js/grouped-product-grid.js | 34 +++++++++++++------ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css b/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css index cd0aa25ae1f88..9142eaf90899e 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/css/grouped-product.css @@ -67,9 +67,8 @@ text-overflow: ellipsis; } - .position { - width:90px; + width: 100px; } .icon-rearrange-position > span { @@ -91,6 +90,11 @@ speak: none; } +.position > * { + float: left; + margin: 3px; +} + .position-widget-input { text-align: center; width: 40px; @@ -103,3 +107,8 @@ .icon-backward:before { content: '\e619'; } + +.icon-rearrange-position, .icon-rearrange-position:hover { + color: #d9d9d9; + text-decoration: none; +} diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 7c9563bb1a0ce..c1a35cb0afede 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -36,7 +36,17 @@ define([ * @param position */ shiftNextPagesPositions: function (position) { - console.log("todo: shifting positions to right on next pages related data"); + var recordData = this.recordData(); + if (~~this.currentPage() === this.pages()) { + return false; + } else { + var startIndex = ~~this.currentPage() * this.pageSize, + offset = position - startIndex + 1; + for (var index = startIndex; index < recordData.length; index++) { + recordData[index].position = index + offset; + } + this.recordData(recordData); + } }, @@ -47,30 +57,36 @@ define([ * @param event */ updateGridPosition: function (data, event) { - var inputValue = ~~event.target.value, + var inputValue = parseInt(event.target.value), recordData = this.recordData(), record, + previousValue, updatedRecord; record = this.elems().find(function (obj) { return obj.dataScope === data.parentScope - }).data(); + }); - if (inputValue === ~~record.positionCalculated) { + previousValue = this.getCalculatedPosition(record); + + if (isNaN(inputValue) || inputValue < 0 || inputValue === previousValue) { return false; } this.elems([]); - updatedRecord = this.getUpdatedRecordIndex(recordData, record.id); + updatedRecord = this.getUpdatedRecordIndex(recordData, record.data().id); if (inputValue >= this.recordData().size() - 1) { recordData[updatedRecord].position = this.getGlobalMaxPosition() + 1; } else { - recordData[updatedRecord].position = inputValue; recordData.forEach(function (value, index) { - if (~~value.id !== ~~record.id) { - recordData[index].position = (index !== inputValue) ? index : index + 1; + if (~~value.id === ~~record.data().id) { + recordData[index].position = inputValue; + } else if (inputValue > previousValue && index <= inputValue) { + recordData[index].position = index - 1; + } else if (inputValue < previousValue && index >= inputValue) { + recordData[index].position = index + 1; } }); } @@ -203,7 +219,5 @@ define([ return ~~r.position })); } - - }); }); From ae03f80da3b6500cf245f06133f528257490852d Mon Sep 17 00:00:00 2001 From: bshevchenko <1408sheva@gmail.com> Date: Thu, 4 Oct 2018 16:50:28 +0300 Subject: [PATCH 165/812] MAGETWO-95332: Update price in shopping cart after product save --- .../StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml index 91f9cbf398d24..b4747a6bf7273 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml @@ -30,6 +30,7 @@ <after> <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> <actionGroup ref="SetCustomerDataLifetimeActionGroup" stepKey="setDefaultCustomerDataLifetime"/> + <magentoCLI command="indexer:reindex customer_grid" stepKey="reindexCustomerGrid"/> <actionGroup ref="logout" stepKey="logout"/> </after> <!--Go to product page--> From 929ed778dd4f6157d2ddfbc49289661559d384eb Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Thu, 4 Oct 2018 18:07:35 +0300 Subject: [PATCH 166/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Magento/Backend/Block/Media/Uploader.php | 6 +++--- .../adminhtml/templates/media/uploader.phtml | 2 +- .../view/adminhtml/web/js/media-uploader.js | 18 ++++++++++-------- .../templates/browser/content/uploader.phtml | 15 ++++++++++----- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php index 1995d72661e2e..22e9197418e4c 100644 --- a/app/code/Magento/Backend/Block/Media/Uploader.php +++ b/app/code/Magento/Backend/Block/Media/Uploader.php @@ -130,11 +130,11 @@ public function getImageUploadMaxHeight() /** * Get image resize configuration * - * @return bool + * @return int */ - public function getIsResizeEnabled(): bool + public function getIsResizeEnabled(): int { - return $this->imageUploadConfig->isResizeEnabled(); + return (int)$this->imageUploadConfig->isResizeEnabled(); } /** diff --git a/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml b/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml index edd54ae38b6a1..d6e97cf4d58e3 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml @@ -13,7 +13,7 @@ data-mage-init='{ "Magento_Backend/js/media-uploader" : { "maxFileSize": <?= /* @escapeNotVerified */ $block->getFileSizeService()->getMaxFileSize() ?>, - "maxWidth":<?= /* @escapeNotVerified */ $block->getImageUploadMaxWidth() ?> , + "maxWidth": <?= /* @escapeNotVerified */ $block->getImageUploadMaxWidth() ?>, "maxHeight": <?= /* @escapeNotVerified */ $block->getImageUploadMaxHeight() ?>, "isResizeEnabled": <?= /* @noEscape */ $block->getIsResizeEnabled() ?> } diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js index 35e9ec244df24..2a15f5262bda1 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js +++ b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js @@ -36,10 +36,17 @@ define([ var self = this, progressTmpl = mageTemplate('[data-template="uploader"]'), - resizeConfig = { - action: 'resize' + isResizeEnabled = this.options.isResizeEnabled, + resizeConfiguration = { + action: 'resize', + maxWidth: this.options.maxWidth, + maxHeight: this.options.maxHeight }; + if (isResizeEnabled === 0) { + resizeConfiguration = {action: 'resize'}; + } + this.element.find('input[type=file]').fileupload({ dataType: 'json', formData: { @@ -123,18 +130,13 @@ define([ stop: fileUploader.uploaderConfig.stop }); - if (typeof this.options.isResizeEnabled !== 'undefined' && this.options.isResizeEnabled === true) { - resizeConfig.maxWidth = this.options.maxWidth; - resizeConfig.maxHeight = this.options.maxHeight; - } - this.element.find('input[type=file]').fileupload('option', { process: [{ action: 'load', fileTypes: /^image\/(gif|jpeg|png)$/, maxFileSize: this.options.maxFileSize }, - resizeConfig, + resizeConfiguration, { action: 'save' }] diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml index 5f4e40667eda5..b1824f639c940 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml @@ -17,6 +17,13 @@ foreach ($filters as $media_type) { }, $media_type['files'])); } +$resizeConfig = ($block->getIsResizeEnabled()) + ? "{action: 'resize', maxWidth: " + . $block->getImageUploadMaxWidth() + . ", maxHeight: " + . $block->getImageUploadMaxHeight() + . "}" + : "{action: 'resize'}"; ?> <div id="<?= $block->getHtmlId() ?>" class="uploader"> @@ -145,11 +152,9 @@ require([ action: 'load', fileTypes: /^image\/(gif|jpeg|png)$/, maxFileSize: <?= (int) $block->getFileSizeService()->getMaxFileSize() ?> * 10 - }, { - action: 'resize', - maxWidth: <?= /* @escapeNotVerified */ $block->getImageUploadMaxWidth() ?> , - maxHeight: <?= /* @escapeNotVerified */ $block->getImageUploadMaxHeight() ?> - }, { + }, + <?= /* @noEscape*/ $resizeConfig ?>, + { action: 'save' }] }); From 3bd78c6897fdccf6deb351b4b3510e979bb673a6 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Thu, 4 Oct 2018 20:42:45 +0300 Subject: [PATCH 167/812] MAGETWO-91650: Translation not working for product alerts - Add foreign key for store table --- app/code/Magento/ProductAlert/etc/db_schema.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ProductAlert/etc/db_schema.xml b/app/code/Magento/ProductAlert/etc/db_schema.xml index 1d145482ea38f..2b3d9c0db3bc5 100644 --- a/app/code/Magento/ProductAlert/etc/db_schema.xml +++ b/app/code/Magento/ProductAlert/etc/db_schema.xml @@ -41,7 +41,7 @@ table="product_alert_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> <constraint xsi:type="foreign" name="PRODUCT_ALERT_PRICE_STORE_ID_STORE_STORE_ID" - table="product_alert_stock" column="website_id" referenceTable="store" + table="product_alert_stock" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> <index name="PRODUCT_ALERT_PRICE_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> @@ -82,7 +82,7 @@ table="product_alert_stock" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_STORE_ID_STORE_STORE_ID" - table="product_alert_stock" column="website_id" referenceTable="store" + table="product_alert_stock" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="product_alert_stock" column="customer_id" referenceTable="customer_entity" From e140d29a3e6ec297be4e8fffdfea07bbc521b971 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 4 Oct 2018 14:57:27 -0500 Subject: [PATCH 168/812] MAGETWO-89232: Validation error appears if duplicate product twice --- .../Model/Exception/UrlAlreadyExistsException.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php b/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php index c7e83819f2569..fdfadc5737af2 100644 --- a/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php +++ b/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php @@ -8,10 +8,12 @@ use Magento\Framework\Phrase; /** + * Exception for already created url. + * * @api * @since 100.2.0 */ -class UrlAlreadyExistsException extends \Magento\Framework\Exception\LocalizedException +class UrlAlreadyExistsException extends \Magento\Framework\Exception\AlreadyExistsException { /** * @var array @@ -34,6 +36,8 @@ public function __construct(Phrase $phrase = null, \Exception $cause = null, $co } /** + * Returns urls. + * * @return array * @since 100.2.0 */ From ee21cf41a961dc35545518e8b0912feab03b600f Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 4 Oct 2018 17:04:13 -0500 Subject: [PATCH 169/812] MAGETWO-71675: Customer can't see available Payment Method for specific country --- .../Magento/Checkout/Model/ShippingInformationManagement.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php index 381ee2b9015c9..77833711e7f2a 100644 --- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php +++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php @@ -151,6 +151,10 @@ public function saveAddressInformation( $address->setCustomerAddressId(null); } + if (!$billingAddress->getCustomerAddressId()) { + $billingAddress->setCustomerAddressId(null); + } + if (!$address->getCountryId()) { throw new StateException(__('The shipping address is missing. Set the address and try again.')); } From 84c7cd8478a6d5fa28d59d4c16e0240af309ee05 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 4 Oct 2018 19:51:03 -0500 Subject: [PATCH 170/812] MAGETWO-71675: Customer can't see available Payment Method for specific country - fix static tests --- .../Model/ShippingInformationManagement.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php index 77833711e7f2a..6bd78cecd3a6b 100644 --- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php +++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php @@ -19,6 +19,9 @@ use Magento\Framework\App\ObjectManager; /** + * Class ShippingInformationManagement + * + * @package Magento\Checkout\Model * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ShippingInformationManagement implements \Magento\Checkout\Api\ShippingInformationManagementInterface @@ -99,8 +102,8 @@ class ShippingInformationManagement implements \Magento\Checkout\Api\ShippingInf * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Quote\Model\Quote\TotalsCollector $totalsCollector - * @param CartExtensionFactory|null $cartExtensionFactory, - * @param ShippingAssignmentFactory|null $shippingAssignmentFactory, + * @param CartExtensionFactory|null $cartExtensionFactory + * @param ShippingAssignmentFactory|null $shippingAssignmentFactory * @param ShippingFactory|null $shippingFactory * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -136,7 +139,14 @@ public function __construct( } /** - * {@inheritDoc} + * Save address information. + * + * @param int $cartId + * @param \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation + * @return \Magento\Checkout\Api\Data\PaymentDetailsInterface + * @throws InputException + * @throws NoSuchEntityException + * @throws StateException */ public function saveAddressInformation( $cartId, @@ -212,6 +222,8 @@ protected function validateQuote(\Magento\Quote\Model\Quote $quote) } /** + * Prepare shipping assignment. + * * @param CartInterface $quote * @param AddressInterface $address * @param string $method From 78e8059da0e05ccdacc0c5b8777dbfa10794e3ed Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Fri, 5 Oct 2018 11:47:10 +0300 Subject: [PATCH 171/812] MAGETWO-91657: Advanced pricing the bulk discounts by percentage returns error when set - Fixed PhpDoc; --- .../Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php index 1f0da62f61056..a529580e29239 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php @@ -54,7 +54,7 @@ public function modifyData(array $data) } /** - * Add tier price info to meta array. {@inheritdoc} + * Add tier price info to meta array. * * @since 101.1.0 * @param array $meta From 3a65d73ff8b2cc5d801de99f182389a52edec318 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 5 Oct 2018 11:52:38 +0300 Subject: [PATCH 172/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Magento/Catalog/etc/adminhtml/system.xml | 17 +++++++++++++++++ app/code/Magento/Catalog/etc/config.xml | 3 +++ 2 files changed, 20 insertions(+) diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml index 71a799fd22427..26da542cde65b 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/system.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml @@ -10,6 +10,9 @@ <tab id="catalog" translate="label" sortOrder="200"> <label>Catalog</label> </tab> + <tab id="advanced" translate="label" sortOrder="999999"> + <label>Advanced</label> + </tab> <section id="catalog" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1"> <class>separator-top</class> <label>Catalog</label> @@ -193,5 +196,19 @@ </field> </group> </section> + <section id="system" translate="label" type="text" sortOrder="900" showInDefault="1" showInWebsite="1" showInStore="1"> + <class>separator-top</class> + <label>System</label> + <tab>advanced</tab> + <resource>Magento_Config::config_system</resource> + <group id="upload_configuration" translate="label" type="text" sortOrder="1000" showInDefault="1" showInWebsite="1" showInStore="1"> + <label>Images Upload Configuration</label> + <field id="jpeg_quality" translate="label comment" type="text" sortOrder="100" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> + <label>Quality</label> + <validate>validate-greater-than-zero validate-number required-entry digits-range-1-100</validate> + <comment>Jpeg quality for images 1-100%.</comment> + </field> + </group> + </section> </system> </config> diff --git a/app/code/Magento/Catalog/etc/config.xml b/app/code/Magento/Catalog/etc/config.xml index f52760aa50743..9c9054dd0ce22 100644 --- a/app/code/Magento/Catalog/etc/config.xml +++ b/app/code/Magento/Catalog/etc/config.xml @@ -66,6 +66,9 @@ <product_custom_options_fodler>custom_options</product_custom_options_fodler> </allowed_resources> </media_storage_configuration> + <upload_configuration> + <jpeg_quality>80</jpeg_quality> + </upload_configuration> </system> <design> <watermark> From f67fe209496c7a674444816ca42157cce94ca3f3 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Fri, 5 Oct 2018 12:14:10 +0300 Subject: [PATCH 173/812] MAGETWO-95329: Customer can place order with new addresses that was edited during checkout with several conditions --- ...eckoutFillNewBillingAddressActionGroup.xml | 6 +- .../Mftf/Section/CheckoutShippingSection.xml | 3 + ...OrderWithNewAddressesThatWasEditedTest.xml | 93 +++++++++++++++++++ ...omerDashboardAccountInformationSection.xml | 3 + .../StorefrontCustomerOrderViewSection.xml | 2 + 5 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml index 5a71b82c15cdb..27e5ed7b6e9ab 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml @@ -44,5 +44,9 @@ <selectOption stepKey="selectCounty" selector="{{classPrefix}} {{CheckoutShippingSection.country}}" userInput="{{Address.country_id}}"/> <waitForPageLoad stepKey="waitForFormUpdate2"/> </actionGroup> - + <!--Filling address without second address field and without state field--> + <actionGroup name="LoggedInCheckoutWithOneAddressFieldWithoutStateField" extends="LoggedInCheckoutFillNewBillingAddressActionGroup"> + <remove keyForRemoval="fillStreetAddress2"/> + <remove keyForRemoval="selectState"/> + </actionGroup> </actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index 494a365ffd507..069e2c74430d3 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -32,5 +32,8 @@ <element name="firstShippingMethod" type="radio" selector="//*[@id='checkout-shipping-method-load']//input[@class='radio']"/> <element name="defaultShipping" type="button" selector=".billing-address-details"/> <element name="stateInput" type="input" selector="input[name=region]"/> + <element name="newAddressModalPopup" type="block" selector=".modal-popup.modal-slide._inner-scroll"/> + <element name="editNewAddress" type="button" selector="//div[@class='shipping-address-item selected-item']//span[text()='Edit']" timeout="30"/> + <element name="closeAddressModalPopup" type="button" selector=".action-hide-popup"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml new file mode 100644 index 0000000000000..c834f8dd9ece9 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml @@ -0,0 +1,93 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest"> + <annotations> + <features value="Checkout"/> + <stories value="Checkout via the Storefront"/> + <title value="Customer Checkout"/> + <description value="Customer can place order with new addresses."/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-67837"/> + <group value="checkout"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + </before> + <after> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + </after> + <!--Go to Storefront as Customer--> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="customerLogin"> + <argument name="Customer" value="$$createCustomer$$" /> + </actionGroup> + + <!-- Add simple product to cart and go to checkout--> + <actionGroup ref="AddSimpleProductToCart" stepKey="addProductToCart"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart" /> + + <!-- Click "+ New Address" and Fill new address--> + <click selector="{{CheckoutShippingSection.newAddressButton}}" stepKey="addAddress"/> + <actionGroup ref="LoggedInCheckoutWithOneAddressFieldWithoutStateField" stepKey="changeAddress"> + <argument name="Address" value="UK_Not_Default_Address"/> + <argument name="classPrefix" value="._show"/> + </actionGroup> + + <!--Click "Save Addresses" --> + <click selector="{{CheckoutShippingSection.saveAddress}}" stepKey="saveAddress"/> + <waitForPageLoad stepKey="waitForAddressSaved"/> + <dontSeeElement selector="{{CheckoutShippingSection.newAddressModalPopup}}" stepKey="dontSeeModalPopup"/> + + <!--Select Shipping Rate "Flat Rate"--> + <click selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('Flat Rate')}}" stepKey="selectFlatShippingMethod"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask2"/> + + <!--Click "Edit" for the new address and clear required fields--> + <click selector="{{CheckoutShippingSection.editNewAddress}}" stepKey="editNewAddress"/> + <clearField selector="._show {{CheckoutShippingSection.firstName}}" stepKey="clearFieldFirstName"/> + <clearField selector="._show {{CheckoutShippingSection.lastName}}" stepKey="clearFieldLastName"/> + <clearField selector="._show {{CheckoutShippingSection.street}}" stepKey="clearFieldStreetAddress1"/> + <clearField selector="._show {{CheckoutShippingSection.city}}" stepKey="clearFieldCityName"/> + <clearField selector="._show {{CheckoutShippingSection.postcode}}" stepKey="clearFieldZip"/> + <selectOption selector="._show {{CheckoutShippingSection.country}}" userInput="" stepKey="clearFieldCounty"/> + <clearField selector="._show {{CheckoutShippingSection.telephone}}" stepKey="clearFieldPhoneNumber"/> + + <!--Close Popup and click next--> + <click selector="{{CheckoutShippingSection.closeAddressModalPopup}}" stepKey="closePopup"/> + <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickNext"/> + + <!--Refresh Page and Place Order--> + <reloadPage stepKey="reloadPage"/> + <waitForElement selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="waitForPlaceOrderButton"/> + <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> + <seeElement selector="{{CheckoutSuccessMainSection.success}}" stepKey="orderIsSuccessfullyPlaced"/> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderLink}}" stepKey="grabOrderNumber"/> + + <!--Verify New addresses in Customer's Address Book--> + <amOnPage url="customer/address/" stepKey="goToCustomerAddressBook"/> + <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" + selector="{{StorefrontCustomerAddressBookSection.addressesList}}" stepKey="checkNewAddresses"/> + <!--Order review page has address that was created during checkout--> + <amOnPage url="sales/order/view/order_id/$grabOrderNumber" stepKey="goToOrderReviewPage"/> + <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" + selector="{{StorefrontCustomerOrderViewSection.shippingAddress}}" stepKey="checkShippingAddress"/> + <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" + selector="{{StorefrontCustomerOrderViewSection.billingAddress}}" stepKey="checkBillingAddress"/> + </test> +</tests> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml index 70d1bb6675db5..a20193f85ed57 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml @@ -24,4 +24,7 @@ <element name="country" type="select" selector="#country"/> <element name="saveAddress" type="button" selector="[data-action='save-address']" timeout="30"/> </section> + <section name="StorefrontCustomerAddressBookSection"> + <element name="addressesList" type="text" selector="//ol[@class='items addresses']//li[@class='item']" /> + </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerOrderViewSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerOrderViewSection.xml index 81612d1c64334..f831aabddd4ee 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerOrderViewSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerOrderViewSection.xml @@ -14,5 +14,7 @@ <element name="subtotal" type="text" selector=".subtotal .amount"/> <element name="paymentMethod" type="text" selector=".payment-method dt"/> <element name="printOrderLink" type="text" selector="a.action.print" timeout="30"/> + <element name="shippingAddress" type="text" selector=".box.box-order-shipping-address"/> + <element name="billingAddress" type="text" selector=".box.box-order-billing-address"/> </section> </sections> From 6209f4107673c89b134e2aacd3a23ae708f383ef Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Thu, 4 Oct 2018 13:50:15 +0300 Subject: [PATCH 174/812] MAGETWO-91784: On Payment screen up and down arrow key allow to add -ve numbers - Trim the first dash in "Credit Card Number" field --- .../credit-card-validation/credit-card-number-validator.js | 2 +- .../base/web/js/model/credit-card-validation/validator.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator.js index 8fb12093e36e4..785b636d5832f 100644 --- a/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator.js +++ b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator.js @@ -36,7 +36,7 @@ define([ return resultWrapper(null, false, false); } - value = value.replace(/\-|\s/g, ''); + value = value.replace(/|\s/g, ''); if (!/^\d*$/.test(value)) { return resultWrapper(null, false, false); diff --git a/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js index c6f1bad31fc07..f9af514a6d4da 100644 --- a/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js +++ b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js @@ -23,6 +23,12 @@ }(function ($, cvvValidator, creditCardNumberValidator, yearValidator, monthValidator, creditCardData) { 'use strict'; + $('.payment-method-content input[type="number"]').on('keyup', function() { + if ($(this).val() < 0) { + $(this).val($(this).val().replace(/^-/, '')); + } + }); + $.each({ 'validate-card-type': [ function (number, item, allowedTypes) { From a71bea80510b8db011812f7052d5f227ebbf2901 Mon Sep 17 00:00:00 2001 From: vprohorov <prohorov.vital@gmail.com> Date: Mon, 17 Sep 2018 11:47:18 +0300 Subject: [PATCH 175/812] MAGETWO-62728: My Wishlist - quantity input box issue - Adding min/max qty checks - Adding js validation --- .../Customer/Wishlist/Item/Column/Cart.php | 26 +++++++++ .../frontend/templates/item/column/cart.phtml | 3 +- .../view/frontend/web/js/add-to-wishlist.js | 56 ++++++++++--------- 3 files changed, 57 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php index b043a8d4b684c..fe0683a52fe97 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php @@ -6,6 +6,8 @@ namespace Magento\Wishlist\Block\Customer\Wishlist\Item\Column; +use Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter; + /** * Wishlist block customer item cart column * @@ -35,4 +37,28 @@ public function getProductItem() { return $this->getItem()->getProduct(); } + + /** + * Get min and max qty for wishlist form. + * + * @return array + */ + public function getMinMaxQty() + { + $stockItem = $this->stockRegistry->getStockItem( + $this->getItem()->getProduct()->getId(), + $this->getItem()->getProduct()->getStore()->getWebsiteId() + ); + + $params = []; + + $params['minAllowed'] = (float)$stockItem->getMinSaleQty(); + if ($stockItem->getMaxSaleQty()) { + $params['maxAllowed'] = (float)$stockItem->getMaxSaleQty(); + } else { + $params['maxAllowed'] = (float)StockDataFilter::MAX_QTY_VALUE; + } + + return $params; + } } diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml index e124edc6a43e1..c1cccae85971c 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml @@ -11,6 +11,7 @@ /** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); $product = $item->getProduct(); +$allowedQty = $block->getMinMaxQty(); ?> <?php foreach ($block->getChildNames() as $childName): ?> <?= /* @noEscape */ $block->getLayout()->renderElement($childName, false) ?> @@ -21,7 +22,7 @@ $product = $item->getProduct(); <div class="field qty"> <label class="label" for="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]"><span><?= $block->escapeHtml(__('Qty')) ?></span></label> <div class="control"> - <input type="number" data-role="qty" id="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true,'maxlength':8}" + <input type="number" data-role="qty" id="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true, 'validate-item-quantity':{'minAllowed':<?= $allowedQty['minAllowed'] ?>,'maxAllowed':<?= $allowedQty['maxAllowed'] ?>}}" name="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" value="<?= /* @noEscape */ (int)($block->getAddToCartQty($item) * 1) ?>"> </div> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js index 7ce934317263b..db5f77348b2c0 100644 --- a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js +++ b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js @@ -63,12 +63,6 @@ define([ isFileUploaded = false, self = this; - if (event.handleObj.selector == this.options.qtyInfo) { //eslint-disable-line eqeqeq - this._updateAddToWishlistButton({}); - event.stopPropagation(); - - return; - } $(event.handleObj.selector).each(function (index, element) { if ($(element).is('input[type=text]') || $(element).is('input[type=email]') || @@ -89,9 +83,7 @@ define([ } }); - if (isFileUploaded) { - this.bindFormSubmit(); - } + this.bindFormSubmit(isFileUploaded); this._updateAddToWishlistButton(dataToAdd); event.stopPropagation(); }, @@ -195,34 +187,44 @@ define([ /** * Bind form submit. + * + @param {boolean} isFileUploaded */ - bindFormSubmit: function () { + bindFormSubmit: function (isFileUploaded) { var self = this; $('[data-action="add-to-wishlist"]').on('click', function (event) { var element, params, form, action; - event.stopPropagation(); - event.preventDefault(); + if (!$($(self.options.qtyInfo).closest('form')).valid()) { + event.stopPropagation(); + event.preventDefault(); + return; + } - element = $('input[type=file]' + self.options.customOptionsInfo); - params = $(event.currentTarget).data('post'); - form = $(element).closest('form'); - action = params.action; + if (isFileUploaded) { - if (params.data.id) { - $('<input>', { - type: 'hidden', - name: 'id', - value: params.data.id - }).appendTo(form); - } + element = $('input[type=file]' + self.options.customOptionsInfo); + params = $(event.currentTarget).data('post'); + form = $(element).closest('form'); + action = params.action; - if (params.data.uenc) { - action += 'uenc/' + params.data.uenc; - } + if (params.data.id) { + $('<input>', { + type: 'hidden', + name: 'id', + value: params.data.id + }).appendTo(form); + } - $(form).attr('action', action).submit(); + if (params.data.uenc) { + action += 'uenc/' + params.data.uenc; + } + + $(form).attr('action', action).submit(); + event.stopPropagation(); + event.preventDefault(); + } }); } }); From 03e8408b6184d3478251f30cc69956a06752503f Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 5 Oct 2018 13:51:24 +0300 Subject: [PATCH 176/812] MAGETWO-91636: Tooltip Position on Mobile out of view range - Fix css styles for 768px --- .../web/css/source/module/checkout/_tooltip.less | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_tooltip.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_tooltip.less index 273f626ec03d6..bf264a98f33b8 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_tooltip.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_tooltip.less @@ -137,9 +137,12 @@ } } -.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { +.media-width(@extremum, @break) when (@extremum = 'max') and (@break >= @screen__m) { .field-tooltip { .field-tooltip-content { + .lib-css(right, @checkout-tooltip-content-mobile__right); + .lib-css(top, @checkout-tooltip-content-mobile__top); + left: auto; &:extend(.abs-checkout-tooltip-content-position-top-mobile all); } } From e194b139c8889587a90aca5cee470e0a40f26422 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 5 Oct 2018 14:04:50 +0300 Subject: [PATCH 177/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- app/code/Magento/Catalog/Helper/Image.php | 1 + .../Magento/Catalog/Model/Product/Image.php | 17 +++++++++++++---- .../Model/Product/Image/ParamsBuilder.php | 9 +++------ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Catalog/Helper/Image.php b/app/code/Magento/Catalog/Helper/Image.php index 758e59790d241..74153267f41d6 100644 --- a/app/code/Magento/Catalog/Helper/Image.php +++ b/app/code/Magento/Catalog/Helper/Image.php @@ -298,6 +298,7 @@ public function resize($width, $height = null) * * @param int $quality * @return $this + * @deprecated */ public function setQuality($quality) { diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php index f1ae9ac62dc9b..564b817fc167e 100644 --- a/app/code/Magento/Catalog/Model/Product/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Image.php @@ -24,6 +24,11 @@ */ class Image extends \Magento\Framework\Model\AbstractModel { + /** + * Config path for the jpeg image quality value + */ + const XML_PATH_JPEG_QUALITY = 'system/upload_configuration/jpeg_quality'; + /** * @var int */ @@ -38,8 +43,9 @@ class Image extends \Magento\Framework\Model\AbstractModel * Default quality value (for JPEG images only). * * @var int + * @deprecated */ - protected $_quality = 80; + protected $_quality = null; /** * @var bool @@ -289,6 +295,7 @@ public function getHeight() * * @param int $quality * @return $this + * @deprecated */ public function setQuality($quality) { @@ -303,7 +310,9 @@ public function setQuality($quality) */ public function getQuality() { - return $this->_quality; + return $this->_quality === null + ? $this->_scopeConfig->getValue(self::XML_PATH_JPEG_QUALITY) + : $this->_quality; } /** @@ -461,7 +470,7 @@ public function getImageProcessor() $this->_processor->keepTransparency($this->_keepTransparency); $this->_processor->constrainOnly($this->_constrainOnly); $this->_processor->backgroundColor($this->_backgroundColor); - $this->_processor->quality($this->_quality); + $this->_processor->quality($this->getQuality()); return $this->_processor; } @@ -843,7 +852,7 @@ private function getMiscParams() 'transparency' => $this->_keepTransparency, 'background' => $this->_backgroundColor, 'angle' => $this->_angle, - 'quality' => $this->_quality + 'quality' => $this->getQuality() ] ); } diff --git a/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php b/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php index dd8d352fecebc..21fde84931fa6 100644 --- a/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php +++ b/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php @@ -10,17 +10,13 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\View\ConfigInterface; use Magento\Store\Model\ScopeInterface; +use Magento\Catalog\Model\Product\Image; /** * Builds parameters array used to build Image Asset */ class ParamsBuilder { - /** - * @var int - */ - private $defaultQuality = 80; - /** * @var array */ @@ -100,11 +96,12 @@ private function overwriteDefaultValues(array $imageArguments): array $transparency = $imageArguments['transparency'] ?? $this->defaultKeepTransparency; $background = $imageArguments['background'] ?? $this->defaultBackground; $angle = $imageArguments['angle'] ?? $this->defaultAngle; + $quality = (int) $this->scopeConfig->getValue(Image::XML_PATH_JPEG_QUALITY); return [ 'background' => (array) $background, 'angle' => $angle, - 'quality' => $this->defaultQuality, + 'quality' => $quality, 'keep_aspect_ratio' => (bool) $aspectRatio, 'keep_frame' => (bool) $frame, 'keep_transparency' => (bool) $transparency, From 8cf76a56cb7d4eb43489e223240f17868a2b8ca4 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Fri, 5 Oct 2018 16:30:57 +0300 Subject: [PATCH 178/812] MAGETWO-91517: Cancel and Return link removes billing and shipping address - Fix statics. --- .../frontend/web/js/model/checkout-data-resolver.js | 13 ++++++++----- .../view/frontend/web/js/view/form/element/email.js | 5 +++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 25abe3c4ed3a0..4abb4c4d61700 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -66,14 +66,15 @@ define([ * Resolve shipping address. Used local storage */ resolveShippingAddress: function () { + var newCustomerShippingAddress; + if (!checkoutData.getShippingAddressFromData() && window.checkoutConfig.shippingAddressFromData ) { checkoutData.setShippingAddressFromData(window.checkoutConfig.shippingAddressFromData); } - var newCustomerShippingAddress = checkoutData.getNewCustomerShippingAddress(); - + newCustomerShippingAddress = checkoutData.getNewCustomerShippingAddress(); if (newCustomerShippingAddress) { createShippingAddress(newCustomerShippingAddress); } @@ -201,15 +202,17 @@ define([ * Resolve billing address. Used local storage */ resolveBillingAddress: function () { + var selectedBillingAddress, + newCustomerBillingAddressData; + if (!checkoutData.getBillingAddressFromData() && window.checkoutConfig.billingAddressFromData ) { checkoutData.setBillingAddressFromData(window.checkoutConfig.billingAddressFromData); } - var selectedBillingAddress = checkoutData.getSelectedBillingAddress(), - newCustomerBillingAddressData = checkoutData.getNewCustomerBillingAddress(); - + selectedBillingAddress = checkoutData.getSelectedBillingAddress(); + newCustomerBillingAddressData = checkoutData.getNewCustomerBillingAddress(); if (selectedBillingAddress) { if (selectedBillingAddress == 'new-customer-address' && newCustomerBillingAddressData) { //eslint-disable-line selectBillingAddress(createBillingAddress(newCustomerBillingAddressData)); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js index 6c0075fca6d51..37a785e292365 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js @@ -17,6 +17,8 @@ define([ ], function ($, Component, ko, customer, checkEmailAvailability, loginAction, quote, checkoutData, fullScreenLoader) { 'use strict'; + var validatedEmail; + if (!checkoutData.getValidatedEmailValue() && window.checkoutConfig.validatedEmailValue ) { @@ -24,8 +26,7 @@ define([ checkoutData.setValidatedEmailValue(window.checkoutConfig.validatedEmailValue); } - var validatedEmail = checkoutData.getValidatedEmailValue(); - + validatedEmail = checkoutData.getValidatedEmailValue(); if (validatedEmail && !customer.isLoggedIn()) { quote.guestEmail = validatedEmail; } From c8a059dc87f1ce4c478d052ba1795e6d92f2cceb Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Fri, 5 Oct 2018 16:23:53 +0300 Subject: [PATCH 179/812] MAGETWO-91496: Instantiating WYSIWYG in DynamicRows - Add wysiwyg suffix to html and js --- .../view/base/web/js/form/element/wysiwyg.js | 20 +++++++++++++++---- .../Framework/Data/Form/Element/Editor.php | 8 ++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js index 6507da5e1a933..0c11ceeb03dae 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js @@ -20,6 +20,7 @@ define([ return Abstract.extend({ defaults: { elementSelector: 'textarea', + suffixRegExpPattern: '\\${ \\$.wysiwygUniqueSuffix }', value: '', $wysiwygEditorButton: '', links: { @@ -61,12 +62,23 @@ define([ return this; }, + /** @inheritdoc */ + initConfig: function (config) { + var pattern = config.suffixRegExpPattern || this.constructor.defaults.suffixRegExpPattern; + + config.content = config.content.replace(new RegExp(pattern, 'g'), this.getUniqueSuffix(config)); + this._super(); + + return this; + }, + /** - * @inheritdoc + * Build unique id based on name, underscore separated. + * + * @param {Object} config */ - destroy: function () { - this._super(); - wysiwyg.removeEvents(this.wysiwygId); + getUniqueSuffix: function (config) { + return config.name.replace(/(\.|-)/g, '_'); }, /** diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Editor.php b/lib/internal/Magento/Framework/Data/Form/Element/Editor.php index c438edf3aa9ac..dee0b6c842f5f 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Editor.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Editor.php @@ -542,4 +542,12 @@ protected function getInlineJs($jsSetupObject, $forceLoad) </script>'; return $jsString; } + + /** + * @inheritdoc + */ + public function getHtmlId() + { + return parent::getHtmlId() . '${ $.wysiwygUniqueSuffix }'; + } } From fa250373443e0a10e9f9472cff69d33754740382 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Fri, 5 Oct 2018 17:11:59 +0300 Subject: [PATCH 180/812] MAGETWO-95329: Customer can place order with new addresses that was edited during checkout with several conditions --- ...eckoutFillNewBillingAddressActionGroup.xml | 16 +++++++++++ .../Test/Mftf/Page/CheckoutShippingPage.xml | 1 + .../CheckoutNewAddressModalPopupSection.xml | 15 ++++++++++ .../Mftf/Section/CheckoutShippingSection.xml | 4 +-- ...OrderWithNewAddressesThatWasEditedTest.xml | 28 +++++++++---------- .../Page/StorefrontCustomerAddressesPage.xml | 14 ++++++++++ .../StorefrontCustomerAddressesSection.xml | 14 ++++++++++ ...omerDashboardAccountInformationSection.xml | 3 -- 8 files changed, 74 insertions(+), 21 deletions(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerAddressesPage.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressesSection.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml index 27e5ed7b6e9ab..62dd6b67b78a6 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml @@ -49,4 +49,20 @@ <remove keyForRemoval="fillStreetAddress2"/> <remove keyForRemoval="selectState"/> </actionGroup> + + <actionGroup name="clearCheckoutAddressPopupFieldsActionGroup"> + <arguments> + <argument name="classPrefix" type="string" defaultValue=""/> + </arguments> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.firstName}}" stepKey="clearFieldFirstName"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.lastName}}" stepKey="clearFieldLastName"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.company}}" stepKey="clearFieldCompany"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.street}}" stepKey="clearFieldStreetAddress1"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.street2}}" stepKey="clearFieldStreetAddress2"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.city}}" stepKey="clearFieldCityName"/> + <selectOption selector="{{classPrefix}} {{CheckoutShippingSection.region}}" userInput="" stepKey="clearFieldRegion"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.postcode}}" stepKey="clearFieldZip"/> + <selectOption selector="{{classPrefix}} {{CheckoutShippingSection.country}}" userInput="" stepKey="clearFieldCounty"/> + <clearField selector="{{classPrefix}} {{CheckoutShippingSection.telephone}}" stepKey="clearFieldPhoneNumber"/> + </actionGroup> </actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml index 07f9e9e6481f7..d13c2d265462b 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml @@ -11,5 +11,6 @@ <page name="CheckoutShippingPage" url="/checkout/#shipping" module="Checkout" area="storefront"> <section name="CheckoutShippingGuestInfoSection"/> <section name="CheckoutShippingSection"/> + <section name="CheckoutNewAddressModalPopupSection"/> </page> </pages> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml new file mode 100644 index 0000000000000..1c523670f7dbb --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml @@ -0,0 +1,15 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="CheckoutNewAddressModalPopupSection"> + <element name="newAddressModalPopup" type="block" selector=".modal-popup.modal-slide._inner-scroll"/> + <element name="closeAddressModalPopup" type="button" selector=".action-hide-popup"/> + </section> +</sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index 069e2c74430d3..cff960946565d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -32,8 +32,6 @@ <element name="firstShippingMethod" type="radio" selector="//*[@id='checkout-shipping-method-load']//input[@class='radio']"/> <element name="defaultShipping" type="button" selector=".billing-address-details"/> <element name="stateInput" type="input" selector="input[name=region]"/> - <element name="newAddressModalPopup" type="block" selector=".modal-popup.modal-slide._inner-scroll"/> - <element name="editNewAddress" type="button" selector="//div[@class='shipping-address-item selected-item']//span[text()='Edit']" timeout="30"/> - <element name="closeAddressModalPopup" type="button" selector=".action-hide-popup"/> + <element name="editActiveAddress" type="button" selector="//div[@class='shipping-address-item selected-item']//span[text()='Edit']" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml index c834f8dd9ece9..0283f6bd108ec 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml @@ -12,7 +12,7 @@ <annotations> <features value="Checkout"/> <stories value="Checkout via the Storefront"/> - <title value="Customer Checkout"/> + <title value="Customer can place order with new addresses that was edited during checkout with several conditions"/> <description value="Customer can place order with new addresses."/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-67837"/> @@ -51,24 +51,19 @@ <!--Click "Save Addresses" --> <click selector="{{CheckoutShippingSection.saveAddress}}" stepKey="saveAddress"/> <waitForPageLoad stepKey="waitForAddressSaved"/> - <dontSeeElement selector="{{CheckoutShippingSection.newAddressModalPopup}}" stepKey="dontSeeModalPopup"/> + <dontSeeElement selector="{{CheckoutNewAddressModalPopupSection.newAddressModalPopup}}" stepKey="dontSeeModalPopup"/> <!--Select Shipping Rate "Flat Rate"--> <click selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('Flat Rate')}}" stepKey="selectFlatShippingMethod"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask2"/> - <!--Click "Edit" for the new address and clear required fields--> - <click selector="{{CheckoutShippingSection.editNewAddress}}" stepKey="editNewAddress"/> - <clearField selector="._show {{CheckoutShippingSection.firstName}}" stepKey="clearFieldFirstName"/> - <clearField selector="._show {{CheckoutShippingSection.lastName}}" stepKey="clearFieldLastName"/> - <clearField selector="._show {{CheckoutShippingSection.street}}" stepKey="clearFieldStreetAddress1"/> - <clearField selector="._show {{CheckoutShippingSection.city}}" stepKey="clearFieldCityName"/> - <clearField selector="._show {{CheckoutShippingSection.postcode}}" stepKey="clearFieldZip"/> - <selectOption selector="._show {{CheckoutShippingSection.country}}" userInput="" stepKey="clearFieldCounty"/> - <clearField selector="._show {{CheckoutShippingSection.telephone}}" stepKey="clearFieldPhoneNumber"/> + <click selector="{{CheckoutShippingSection.editActiveAddress}}" stepKey="editNewAddress"/> + <actionGroup ref="clearCheckoutAddressPopupFieldsActionGroup" stepKey="clearRequiredFields"> + <argument name="classPrefix" value="._show"/> + </actionGroup> <!--Close Popup and click next--> - <click selector="{{CheckoutShippingSection.closeAddressModalPopup}}" stepKey="closePopup"/> + <click selector="{{CheckoutNewAddressModalPopupSection.closeAddressModalPopup}}" stepKey="closePopup"/> <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" stepKey="waitForNextButton"/> <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickNext"/> @@ -80,14 +75,17 @@ <grabTextFrom selector="{{CheckoutSuccessMainSection.orderLink}}" stepKey="grabOrderNumber"/> <!--Verify New addresses in Customer's Address Book--> - <amOnPage url="customer/address/" stepKey="goToCustomerAddressBook"/> + <amOnPage url="{{StorefrontCustomerAddressesPage.url}}" stepKey="goToCustomerAddressBook"/> <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" - selector="{{StorefrontCustomerAddressBookSection.addressesList}}" stepKey="checkNewAddresses"/> + selector="{{StorefrontCustomerAddressesSection.addressesList}}" stepKey="checkNewAddresses"/> <!--Order review page has address that was created during checkout--> - <amOnPage url="sales/order/view/order_id/$grabOrderNumber" stepKey="goToOrderReviewPage"/> + <amOnPage url="{{StorefrontCustomerOrderViewPage.url({$grabOrderNumber})}}" stepKey="goToOrderReviewPage"/> <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" selector="{{StorefrontCustomerOrderViewSection.shippingAddress}}" stepKey="checkShippingAddress"/> <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" selector="{{StorefrontCustomerOrderViewSection.billingAddress}}" stepKey="checkBillingAddress"/> + + <!--Logout from customer account--> + <amOnPage url="customer/account/logout/" stepKey="logoutCustomer"/> </test> </tests> diff --git a/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerAddressesPage.xml b/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerAddressesPage.xml new file mode 100644 index 0000000000000..b9bede5133060 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerAddressesPage.xml @@ -0,0 +1,14 @@ +<?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="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="StorefrontCustomerAddressesPage" url="/customer/address/" area="storefront" module="Magento_Customer"> + <section name="StorefrontCustomerAddressesSection"/> + </page> +</pages> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressesSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressesSection.xml new file mode 100644 index 0000000000000..8a6a98ff45a6a --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerAddressesSection.xml @@ -0,0 +1,14 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontCustomerAddressesSection"> + <element name="addressesList" type="text" selector=".block-addresses-list" /> + </section> +</sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml index a20193f85ed57..70d1bb6675db5 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml @@ -24,7 +24,4 @@ <element name="country" type="select" selector="#country"/> <element name="saveAddress" type="button" selector="[data-action='save-address']" timeout="30"/> </section> - <section name="StorefrontCustomerAddressBookSection"> - <element name="addressesList" type="text" selector="//ol[@class='items addresses']//li[@class='item']" /> - </section> </sections> From 77af6f7d21949eaac1866dfbbbfb4ec1b424a407 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Fri, 5 Oct 2018 17:14:37 +0300 Subject: [PATCH 181/812] MAGETWO-95329: Customer can place order with new addresses that was edited during checkout with several conditions --- .../Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml | 2 +- ...pupSection.xml => StorefrontCheckoutAddressPopupSection.xml} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename app/code/Magento/Checkout/Test/Mftf/Section/{CheckoutNewAddressModalPopupSection.xml => StorefrontCheckoutAddressPopupSection.xml} (90%) diff --git a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml index d13c2d265462b..c8641f7d8fbf3 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml @@ -11,6 +11,6 @@ <page name="CheckoutShippingPage" url="/checkout/#shipping" module="Checkout" area="storefront"> <section name="CheckoutShippingGuestInfoSection"/> <section name="CheckoutShippingSection"/> - <section name="CheckoutNewAddressModalPopupSection"/> + <section name="StorefrontCheckoutAddressPopupSection"/> </page> </pages> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutAddressPopupSection.xml similarity index 90% rename from app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml rename to app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutAddressPopupSection.xml index 1c523670f7dbb..6a27915768dd7 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutNewAddressModalPopupSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutAddressPopupSection.xml @@ -8,7 +8,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="CheckoutNewAddressModalPopupSection"> + <section name="StorefrontCheckoutAddressPopupSection"> <element name="newAddressModalPopup" type="block" selector=".modal-popup.modal-slide._inner-scroll"/> <element name="closeAddressModalPopup" type="button" selector=".action-hide-popup"/> </section> From 2bee3660f183af1439b111557b3b958b3c812b25 Mon Sep 17 00:00:00 2001 From: Peter O'Callaghan <contact@peterocallaghan.co.uk> Date: Sat, 6 Oct 2018 10:28:25 +0100 Subject: [PATCH 182/812] Fixes #18357 - SQL error when table prefix used. --- .../Model/ResourceModel/Agreement/Grid/Collection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php b/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php index 70794d24a64eb..78ad7b32330ad 100644 --- a/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php +++ b/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php @@ -64,7 +64,7 @@ private function getStoresForAgreements() if (!empty($agreementId)) { $select = $this->getConnection()->select()->from( - ['agreement_store' => 'checkout_agreement_store'] + ['agreement_store' => $this->getResource()->getTable('checkout_agreement_store')] )->where( 'agreement_store.agreement_id IN (?)', $agreementId From 87cfb718edcde6b21375e398dbc8fd35cb84dcbe Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Sat, 6 Oct 2018 12:40:15 +0200 Subject: [PATCH 183/812] Working concept for setting shipping address for a shopping cart --- .../SetShippingMethodsOnCart.php | 81 +++++++++++++------ .../Magento/QuoteGraphQl/etc/schema.graphqls | 8 +- 2 files changed, 61 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php index f2e1be3bb0508..c2d14668a2e70 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php @@ -7,7 +7,8 @@ namespace Magento\QuoteGraphQl\Model\Resolver\ShippingMethod; -use Magento\Framework\Exception\CouldNotSaveException; +use Magento\Checkout\Api\ShippingInformationManagementInterface; +use Magento\Checkout\Model\ShippingInformation; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; @@ -19,8 +20,10 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\Stdlib\ArrayManager; use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; -use Magento\Quote\Model\ShippingMethodManagementInterface; use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser; +use Magento\Quote\Model\Quote\AddressFactory as QuoteAddressFactory; +use Magento\Quote\Model\ResourceModel\Quote\Address as QuoteAddressResource; +use Magento\Checkout\Model\ShippingInformationFactory; /** * Class SetShippingMethodsOnCart @@ -29,41 +32,64 @@ */ class SetShippingMethodsOnCart implements ResolverInterface { + /** + * @var ShippingInformationFactory + */ + private $shippingInformationFactory; + + /** + * @var QuoteAddressFactory + */ + private $quoteAddressFactory; + + /** + * @var QuoteAddressResource + */ + private $quoteAddressResource; + /** * @var MaskedQuoteIdToQuoteIdInterface */ private $maskedQuoteIdToQuoteId; + /** * @var ArrayManager */ private $arrayManager; /** - * @var ShippingMethodManagementInterface + * @var IsCartMutationAllowedForCurrentUser */ - private $shippingMethodManagement; + private $isCartMutationAllowedForCurrentUser; /** - * @var IsCartMutationAllowedForCurrentUser + * @var ShippingInformationManagementInterface */ - private $isCartMutationAllowedForCurrentUser; + private $shippingInformationManagement; /** * SetShippingMethodsOnCart constructor. * @param ArrayManager $arrayManager * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId - * @param ShippingMethodManagementInterface $shippingMethodManagement + * @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser */ public function __construct( ArrayManager $arrayManager, MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, - ShippingMethodManagementInterface $shippingMethodManagement, - IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser + IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser, + ShippingInformationManagementInterface $shippingInformationManagement, + QuoteAddressFactory $quoteAddressFacrory, + QuoteAddressResource $quoteAddressResource, + ShippingInformationFactory $shippingInformationFactory ) { $this->arrayManager = $arrayManager; $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->shippingMethodManagement = $shippingMethodManagement; $this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser; + $this->shippingInformationManagement = $shippingInformationManagement; + + $this->quoteAddressResource = $quoteAddressResource; + $this->quoteAddressFactory = $quoteAddressFacrory; + $this->shippingInformationFactory = $shippingInformationFactory; } /** @@ -77,17 +103,18 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value if (!$maskedCartId) { throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); } - if (!$shippingMethods) { throw new GraphQlInputException(__('Required parameter "shipping_methods" is missing')); } $shippingMethod = reset($shippingMethods); // TODO: provide implementation for multishipping + if (!$shippingMethod['cart_address_id']) { + throw new GraphQlInputException(__('Required parameter "cart_address_id" is missing')); + } if (!$shippingMethod['shipping_carrier_code']) { // FIXME: check the E_WARNING here throw new GraphQlInputException(__('Required parameter "shipping_carrier_code" is missing')); } - if (!$shippingMethod['shipping_method_code']) { // FIXME: check the E_WARNING here throw new GraphQlInputException(__('Required parameter "shipping_method_code" is missing')); } @@ -109,22 +136,28 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value ); } + $quoteAddress = $this->quoteAddressFactory->create(); + $this->quoteAddressResource->load($quoteAddress, $shippingMethod['cart_address_id']); + + /** @var ShippingInformation $shippingInformation */ + $shippingInformation = $this->shippingInformationFactory->create(); + + /* If the address is not a shipping address (but billing) the system will find the proper shipping address for + the selected cart and set the information there (actual for single shipping address) */ + $shippingInformation->setShippingAddress($quoteAddress); + $shippingInformation->setShippingCarrierCode($shippingMethod['shipping_carrier_code']); + $shippingInformation->setShippingMethodCode($shippingMethod['shipping_method_code']); + try { - $this->shippingMethodManagement->set( - $cartId, - $shippingMethods['shipping_carrier_code'], - $shippingMethods['shipping_method_code'] - ); - } catch (InputException $exception) { - throw new GraphQlInputException(__($exception->getMessage())); - } catch (CouldNotSaveException $exception) { - throw new GraphQlInputException(__($exception->getMessage())); - } catch (StateException $exception) { - throw new GraphQlInputException(__($exception->getMessage())); + $this->shippingInformationManagement->saveAddressInformation($cartId, $shippingInformation); } catch (NoSuchEntityException $exception) { throw new GraphQlNoSuchEntityException(__($exception->getMessage())); + } catch (StateException $exception) { + throw new GraphQlInputException(__($exception->getMessage())); + } catch (InputException $exception) { + throw new GraphQlInputException(__($exception->getMessage())); } return 'Success!'; // TODO we should return cart here } -} \ No newline at end of file +} diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 45f98daeaed06..730a54377b370 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -6,9 +6,9 @@ type Query { } type Mutation { - createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") - applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") - removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") + createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") + applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ApplyCouponToCart") + removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveCouponFromCart") setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ShippingMethod\\SetShippingMethodsOnCart") @@ -53,7 +53,7 @@ input SetShippingMethodsOnCartInput { } input ShippingMethodForAddressInput { - cart_address_id: int + cart_address_id: Int! shipping_carrier_code: String! shipping_method_code: String! } From 8f36157cae89483469d567710aaba1d728328dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Eisenf=C3=BChrer?= <m.eisenfuehrer@techdivision.com> Date: Sat, 6 Oct 2018 16:57:46 +0200 Subject: [PATCH 184/812] fix issue 12399 --- .../Controller/Adminhtml/Promo/Catalog/Save.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index bad1118e3ae72..4d3b36c7fe69c 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -61,6 +61,17 @@ public function execute() ['request' => $this->getRequest()] ); $data = $this->getRequest()->getPostValue(); + + $filterValues = ['from_date' => $this->_dateFilter]; + if ($this->getRequest()->getParam('to_date')) { + $filterValues['to_date'] = $this->_dateFilter; + } + $inputFilter = new \Zend_Filter_Input( + $filterValues, + [], + $data + ); + $data = $inputFilter->getUnescaped(); $id = $this->getRequest()->getParam('rule_id'); if ($id) { $model = $ruleRepository->get($id); From 320c0aab8787cfc3f63a4f170f4711c614c0e715 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <ihor-sviziev@users.noreply.github.com> Date: Sun, 7 Oct 2018 08:48:28 +0300 Subject: [PATCH 185/812] Support of error pages behind a load balancer that serves HTTPS Use strict comparison --- pub/errors/processor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 3958c6d152c9d..2bb25f3fd587d 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -265,7 +265,7 @@ public function getHostUrl() $host = 'localhost'; } - $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off') + $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] !== 'off') || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'); $url = ($isSecure ? 'https://' : 'http://') . $host; From 0d97a1600e3ccb3b3cf5c024a971b6f7b3597a3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Eisenf=C3=BChrer?= <m.eisenfuehrer@techdivision.com> Date: Sun, 7 Oct 2018 10:41:26 +0200 Subject: [PATCH 186/812] fix documentation for phpcs --- .../Controller/Adminhtml/Promo/Catalog/Save.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index 4d3b36c7fe69c..b09598d4fd76f 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -14,7 +14,8 @@ use Magento\Framework\App\Request\DataPersistorInterface; /** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * Save action for catalog rule + * @package Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog */ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog implements HttpPostActionInterface { @@ -40,7 +41,9 @@ public function __construct( } /** - * @return void + * Execute save action from catalog rule + * + * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function execute() From 745e7575a7e41fa5dfd086d0ad067c990781c553 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Sun, 7 Oct 2018 12:12:30 +0300 Subject: [PATCH 187/812] MAGETWO-81469: Cached Config is Different From DB --- .../Magento/Config/App/Config/Type/System.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index f5d109b198d5a..d120b80fc2750 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -121,7 +121,7 @@ public function __construct( public function get($path = '') { if ($path === '') { - $this->data = array_replace_recursive($this->loadAllData(), $this->data); + $this->data = array_replace_recursive($this->data, $this->loadAllData()); return $this->data; } @@ -142,7 +142,7 @@ private function getWithParts($path) if (count($pathParts) === 1 && $pathParts[0] !== ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$pathParts[0]])) { $data = $this->readData(); - $this->data = array_replace_recursive($data, $this->data); + $this->data = $this->postProcessor->process($data); } return $this->data[$pathParts[0]]; @@ -152,7 +152,7 @@ private function getWithParts($path) if ($scopeType === ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$scopeType])) { - $this->data = array_replace_recursive($this->loadDefaultScopeData($scopeType), $this->data); + $this->data = array_replace_recursive($this->data, $this->loadDefaultScopeData($scopeType)); } return $this->getDataByPathParts($this->data[$scopeType], $pathParts); @@ -162,10 +162,7 @@ private function getWithParts($path) if (!isset($this->data[$scopeType][$scopeId])) { $scopeData = $this->loadScopeData($scopeType, $scopeId); - - if (!isset($this->data[$scopeType][$scopeId])) { - $this->data = array_replace_recursive($scopeData, $this->data); - } + $this->data = array_replace_recursive($this->data, $scopeData); } return isset($this->data[$scopeType][$scopeId]) @@ -187,6 +184,7 @@ private function loadAllData() } else { $data = $this->serializer->unserialize($cachedData); } + $data = $this->postProcessor->process($data); return $data; } @@ -207,6 +205,7 @@ private function loadDefaultScopeData($scopeType) } else { $data = [$scopeType => $this->serializer->unserialize($cachedData)]; } + $data = $this->postProcessor->process($data); return $data; } @@ -237,6 +236,7 @@ private function loadScopeData($scopeType, $scopeId) } else { $data = [$scopeType => [$scopeId => $this->serializer->unserialize($cachedData)]]; } + $data = $this->postProcessor->process($data); return $data; } @@ -308,9 +308,6 @@ private function getDataByPathParts($data, $pathParts) private function readData(): array { $this->data = $this->reader->read(); - $this->data = $this->postProcessor->process( - $this->data - ); return $this->data; } From 2f655dd50fb276ff5d567165074264a5a6b778bd Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Sun, 7 Oct 2018 12:14:11 +0300 Subject: [PATCH 188/812] MAGETWO-81469: Cached Config is Different From DB --- app/code/Magento/Config/App/Config/Type/System.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index d120b80fc2750..ab4e985ee4a6e 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -101,6 +101,8 @@ public function __construct( } /** + * Get config value by path. + * * System configuration is separated by scopes (default, websites, stores). Configuration of a scope is inherited * from its parent scope (store inherits website). * @@ -243,6 +245,7 @@ private function loadScopeData($scopeType, $scopeId) /** * Cache configuration data. + * * Caches data per scope to avoid reading data for all scopes on every request * * @param array $data From e1e7b14ecb70e295f0e9a9cdc806712fe3a16c57 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Sun, 7 Oct 2018 12:59:57 +0300 Subject: [PATCH 189/812] MAGETWO-81469: Cached Config is Different From DB --- app/code/Magento/Config/App/Config/Type/System.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index ab4e985ee4a6e..1fff1aedcfac1 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -123,7 +123,9 @@ public function __construct( public function get($path = '') { if ($path === '') { - $this->data = array_replace_recursive($this->data, $this->loadAllData()); + $this->data = array_replace_recursive($this->data, $allData = $this->loadAllData()); + $allData = $this->postProcessor->process($allData); + $this->data = array_replace_recursive($this->data, $allData); return $this->data; } @@ -154,7 +156,9 @@ private function getWithParts($path) if ($scopeType === ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$scopeType])) { - $this->data = array_replace_recursive($this->data, $this->loadDefaultScopeData($scopeType)); + $this->data = array_replace_recursive($this->data, $scopeData = $this->loadDefaultScopeData($scopeType)); + $scopeData = $this->postProcessor->process($scopeData); + $this->data = array_replace_recursive($this->data, $scopeData); } return $this->getDataByPathParts($this->data[$scopeType], $pathParts); @@ -165,6 +169,8 @@ private function getWithParts($path) if (!isset($this->data[$scopeType][$scopeId])) { $scopeData = $this->loadScopeData($scopeType, $scopeId); $this->data = array_replace_recursive($this->data, $scopeData); + $scopeData = $this->postProcessor->process($scopeData); + $this->data = array_replace_recursive($this->data, $scopeData); } return isset($this->data[$scopeType][$scopeId]) @@ -186,7 +192,6 @@ private function loadAllData() } else { $data = $this->serializer->unserialize($cachedData); } - $data = $this->postProcessor->process($data); return $data; } @@ -207,7 +212,6 @@ private function loadDefaultScopeData($scopeType) } else { $data = [$scopeType => $this->serializer->unserialize($cachedData)]; } - $data = $this->postProcessor->process($data); return $data; } @@ -238,7 +242,6 @@ private function loadScopeData($scopeType, $scopeId) } else { $data = [$scopeType => [$scopeId => $this->serializer->unserialize($cachedData)]]; } - $data = $this->postProcessor->process($data); return $data; } From e4c752b54df53234c6501d6080a729a3fc038a86 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Sun, 7 Oct 2018 13:06:28 +0300 Subject: [PATCH 190/812] MAGETWO-81469: Cached Config is Different From DB --- app/code/Magento/Config/App/Config/Type/System.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 1fff1aedcfac1..c80b2141294e6 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -156,7 +156,10 @@ private function getWithParts($path) if ($scopeType === ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$scopeType])) { - $this->data = array_replace_recursive($this->data, $scopeData = $this->loadDefaultScopeData($scopeType)); + $this->data = array_replace_recursive( + $this->data, + $scopeData = $this->loadDefaultScopeData($scopeType) + ); $scopeData = $this->postProcessor->process($scopeData); $this->data = array_replace_recursive($this->data, $scopeData); } From cbea532e42e33e9e7778f3fd732a41404efb80b2 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Sun, 7 Oct 2018 13:48:52 +0300 Subject: [PATCH 191/812] MAGETWO-81469: Cached Config is Different From DB --- app/code/Magento/Config/App/Config/Type/System.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index c80b2141294e6..2b65c2791365a 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -123,9 +123,7 @@ public function __construct( public function get($path = '') { if ($path === '') { - $this->data = array_replace_recursive($this->data, $allData = $this->loadAllData()); - $allData = $this->postProcessor->process($allData); - $this->data = array_replace_recursive($this->data, $allData); + $this->data = array_replace_recursive($this->data, $this->loadAllData()); return $this->data; } @@ -146,7 +144,7 @@ private function getWithParts($path) if (count($pathParts) === 1 && $pathParts[0] !== ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$pathParts[0]])) { $data = $this->readData(); - $this->data = $this->postProcessor->process($data); + $this->data = array_replace_recursive($this->data, $this->postProcessor->process($data)); } return $this->data[$pathParts[0]]; @@ -194,9 +192,10 @@ private function loadAllData() $data = $this->readData(); } else { $data = $this->serializer->unserialize($cachedData); + $this->data = $data; } - return $data; + return $this->postProcessor->process($data); } /** From d4735edfa9ba6fb98007c9073339025571297d22 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Sun, 7 Oct 2018 14:19:30 +0300 Subject: [PATCH 192/812] MAGETWO-95329: Customer can place order with new addresses that was edited during checkout with several conditions --- ...ontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml index 0283f6bd108ec..9d805589eb831 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml @@ -51,7 +51,7 @@ <!--Click "Save Addresses" --> <click selector="{{CheckoutShippingSection.saveAddress}}" stepKey="saveAddress"/> <waitForPageLoad stepKey="waitForAddressSaved"/> - <dontSeeElement selector="{{CheckoutNewAddressModalPopupSection.newAddressModalPopup}}" stepKey="dontSeeModalPopup"/> + <dontSeeElement selector="{{StorefrontCheckoutAddressPopupSection.newAddressModalPopup}}" stepKey="dontSeeModalPopup"/> <!--Select Shipping Rate "Flat Rate"--> <click selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('Flat Rate')}}" stepKey="selectFlatShippingMethod"/> @@ -63,7 +63,7 @@ </actionGroup> <!--Close Popup and click next--> - <click selector="{{CheckoutNewAddressModalPopupSection.closeAddressModalPopup}}" stepKey="closePopup"/> + <click selector="{{StorefrontCheckoutAddressPopupSection.closeAddressModalPopup}}" stepKey="closePopup"/> <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" stepKey="waitForNextButton"/> <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickNext"/> From ba703d7d22923239c4519616b6c6ab21124ec8bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Eisenf=C3=BChrer?= <m.eisenfuehrer@techdivision.com> Date: Sun, 7 Oct 2018 14:24:52 +0200 Subject: [PATCH 193/812] fix one line for static test --- .../CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index b09598d4fd76f..d770d674bb3e6 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -15,6 +15,7 @@ /** * Save action for catalog rule + * * @package Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog */ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog implements HttpPostActionInterface From d11ef56535da099158cc302eff104c2b466f2af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Eisenf=C3=BChrer?= <m.eisenfuehrer@techdivision.com> Date: Mon, 8 Oct 2018 08:09:14 +0200 Subject: [PATCH 194/812] fix: add SuppressWarnings again --- .../CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index d770d674bb3e6..0ff12faf54cbf 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -15,8 +15,8 @@ /** * Save action for catalog rule - * - * @package Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog implements HttpPostActionInterface { From 34e8f843b314da86a4294522e74142b82b89be05 Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Mon, 8 Oct 2018 10:24:06 +0300 Subject: [PATCH 195/812] MAGETWO-95450: Unskip MFTF tests StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest --- ...ntTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml index 9bc44dec0b5b8..9ea4793242fe8 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml @@ -18,9 +18,6 @@ <testCaseId value="MAGETWO-41930"/> <group value="checkout"/> <group value="tax"/> - <skip> - <issueId value="MAGETWO-90966"/> - </skip> </annotations> <before> <!-- Preconditions --> From 18af30faafb267783d004617e75f998c97e3d84f Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Mon, 8 Oct 2018 10:55:38 +0300 Subject: [PATCH 196/812] MAGETWO-95329: Customer can place order with new addresses that was edited during checkout with several conditions --- ...PlaceOrderWithNewAddressesThatWasEditedTest.xml | 2 +- .../StorefrontCustomerLogoutActionGroup.xml | 14 ++++++++++++++ .../Mftf/Page/StorefrontCustomerLogoutPage.xml | 11 +++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerLogoutActionGroup.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerLogoutPage.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml index 9d805589eb831..274e32653d8e6 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml @@ -86,6 +86,6 @@ selector="{{StorefrontCustomerOrderViewSection.billingAddress}}" stepKey="checkBillingAddress"/> <!--Logout from customer account--> - <amOnPage url="customer/account/logout/" stepKey="logoutCustomer"/> + <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer"/> </test> </tests> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerLogoutActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerLogoutActionGroup.xml new file mode 100644 index 0000000000000..5497b083ab5ad --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontCustomerLogoutActionGroup.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="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StorefrontCustomerLogoutActionGroup"> + <amOnPage url="{{StorefrontCustomerLogoutPage.url}}" stepKey="storefrontSignOut"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerLogoutPage.xml b/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerLogoutPage.xml new file mode 100644 index 0000000000000..b3cea8f2c2939 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Page/StorefrontCustomerLogoutPage.xml @@ -0,0 +1,11 @@ +<?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="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="StorefrontCustomerLogoutPage" url="customer/account/logout/" area="storefront" module="Magento_Customer"/> +</pages> From 65b4bf1be923344c575effb445444ac542f00712 Mon Sep 17 00:00:00 2001 From: Vincent MARMIESSE <vincent.marmiesse@ph2m.com> Date: Thu, 4 Oct 2018 19:32:37 +0200 Subject: [PATCH 197/812] Add class into image builder --- .../Magento/Catalog/Block/Product/Image.php | 3 +++ .../Catalog/Block/Product/ImageFactory.php | 24 +++++++++++++++---- .../Unit/Block/Product/ImageFactoryTest.php | 7 ++++-- .../product/image_with_borders.phtml | 2 +- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/Image.php b/app/code/Magento/Catalog/Block/Product/Image.php index 20a556ab41451..7a7f9c0affc7d 100644 --- a/app/code/Magento/Catalog/Block/Product/Image.php +++ b/app/code/Magento/Catalog/Block/Product/Image.php @@ -6,6 +6,8 @@ namespace Magento\Catalog\Block\Product; /** + * Product image block + * * @api * @method string getImageUrl() * @method string getWidth() @@ -13,6 +15,7 @@ * @method string getLabel() * @method float getRatio() * @method string getCustomAttributes() + * @method string getClass() * @since 100.0.2 */ class Image extends \Magento\Framework\View\Element\Template diff --git a/app/code/Magento/Catalog/Block/Product/ImageFactory.php b/app/code/Magento/Catalog/Block/Product/ImageFactory.php index f9a576367ddeb..aa303af656a5b 100644 --- a/app/code/Magento/Catalog/Block/Product/ImageFactory.php +++ b/app/code/Magento/Catalog/Block/Product/ImageFactory.php @@ -77,16 +77,29 @@ private function getStringCustomAttributes(array $attributes): string { $result = []; foreach ($attributes as $name => $value) { - $result[] = $name . '="' . $value . '"'; + if ($name != 'class') { + $result[] = $name . '="' . $value . '"'; + } } return !empty($result) ? implode(' ', $result) : ''; } + /** + * Retrieve image class for HTML element + * + * @param array $attributes + * @return string + */ + private function getClass(array $attributes): string + { + return $attributes['class'] ?? 'product-image-photo'; + } + /** * Calculate image ratio * - * @param $width - * @param $height + * @param int $width + * @param int $height * @return float */ private function getRatio(int $width, int $height): float @@ -98,8 +111,9 @@ private function getRatio(int $width, int $height): float } /** - * @param Product $product + * Get image label * + * @param Product $product * @param string $imageType * @return string */ @@ -114,6 +128,7 @@ private function getLabel(Product $product, string $imageType): string /** * Create image block from product + * * @param Product $product * @param string $imageId * @param array|null $attributes @@ -154,6 +169,7 @@ public function create(Product $product, string $imageId, array $attributes = nu 'label' => $this->getLabel($product, $imageMiscParams['image_type']), 'ratio' => $this->getRatio($imageMiscParams['image_width'], $imageMiscParams['image_height']), 'custom_attributes' => $this->getStringCustomAttributes($attributes), + 'class' => $this->getClass($attributes), 'product_id' => $product->getId() ], ]; diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/ImageFactoryTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/ImageFactoryTest.php index 8a42865a3fe4d..95b06e40602bf 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/ImageFactoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/ImageFactoryTest.php @@ -145,7 +145,8 @@ private function getTestDataWithoutAttributes(): array 'label' => 'test_image_label', 'ratio' => 1, 'custom_attributes' => '', - 'product_id' => null + 'product_id' => null, + 'class' => 'product-image-photo' ], ], ]; @@ -190,6 +191,7 @@ private function getTestDataWithAttributes(): array 'custom_attributes' => [ 'name_1' => 'value_1', 'name_2' => 'value_2', + 'class' => 'my-class' ], ], 'expected' => [ @@ -201,7 +203,8 @@ private function getTestDataWithAttributes(): array 'label' => 'test_product_name', 'ratio' => 0.5, // <== 'custom_attributes' => 'name_1="value_1" name_2="value_2"', - 'product_id' => null + 'product_id' => null, + 'class' => 'my-class' ], ], ]; diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/image_with_borders.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/image_with_borders.phtml index 74a0b2d7cf1a3..8a907bd54aa6a 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/image_with_borders.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/image_with_borders.phtml @@ -10,7 +10,7 @@ style="width:<?= /* @escapeNotVerified */ $block->getWidth() ?>px;"> <span class="product-image-wrapper" style="padding-bottom: <?= /* @escapeNotVerified */ ($block->getRatio() * 100) ?>%;"> - <img class="product-image-photo" + <img class="<?= /* @escapeNotVerified */ $block->getClass() ?>" <?= /* @escapeNotVerified */ $block->getCustomAttributes() ?> src="<?= /* @escapeNotVerified */ $block->getImageUrl() ?>" max-width="<?= /* @escapeNotVerified */ $block->getWidth() ?>" From c510fd217e7bf27cca98dfc49daf18a2ae56774b Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Mon, 8 Oct 2018 11:35:11 +0300 Subject: [PATCH 198/812] MAGETWO-81469: Cached Config is Different From DB --- .../App/Config/MetadataConfigTypeProcessor.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php b/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php index 6eb5fd7e9d3b1..0b6630c4d6c0a 100644 --- a/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php +++ b/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php @@ -114,9 +114,14 @@ private function processScopeData( $scopeCode = null ) { foreach ($this->_metadata as $path => $metadata) { - $configPath = $this->configPathResolver->resolve($path, $scope, $scopeCode); - if (!empty($this->configSource->get($configPath))) { - continue; + try { + $configPath = $this->configPathResolver->resolve($path, $scope, $scopeCode); + if (!empty($this->configSource->get($configPath))) { + continue; + } + } catch (\Throwable $exception) { + //Failed to load scopes or config source, perhaps config data received is outdated. + return $data; } /** @var \Magento\Framework\App\Config\Data\ProcessorInterface $processor */ $processor = $this->_processorFactory->get($metadata['backendModel']); From 4da3b5410e7525a4ea00b4df7c1c6f5a3f2ae5b4 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Mon, 8 Oct 2018 11:56:39 +0300 Subject: [PATCH 199/812] MAGETWO-95329: Customer can place order with new addresses that was edited during checkout with several conditions --- ...tCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml index 274e32653d8e6..cc5e723c72ea0 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerPlaceOrderWithNewAddressesThatWasEditedTest.xml @@ -26,6 +26,9 @@ <createData entity="Simple_US_Customer" stepKey="createCustomer"/> </before> <after> + <!--Logout from customer account--> + <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> @@ -84,8 +87,5 @@ selector="{{StorefrontCustomerOrderViewSection.shippingAddress}}" stepKey="checkShippingAddress"/> <see userInput="{{UK_Not_Default_Address.street[0]}} {{UK_Not_Default_Address.city}}, {{UK_Not_Default_Address.postcode}}" selector="{{StorefrontCustomerOrderViewSection.billingAddress}}" stepKey="checkBillingAddress"/> - - <!--Logout from customer account--> - <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer"/> </test> </tests> From 57807206530e19e86501d2f2248911464f03ee99 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Mon, 8 Oct 2018 12:39:25 +0300 Subject: [PATCH 200/812] MAGETWO-81469: Cached Config is Different From DB --- .../Framework/App/Config/MetadataConfigTypeProcessor.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php b/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php index 0b6630c4d6c0a..bc23032903d23 100644 --- a/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php +++ b/lib/internal/Magento/Framework/App/Config/MetadataConfigTypeProcessor.php @@ -11,6 +11,9 @@ use Magento\Framework\App\Config\Spi\PostProcessorInterface; use Magento\Framework\App\ObjectManager; +/** + * Post-process config values using their backend models. + */ class MetadataConfigTypeProcessor implements PostProcessorInterface { /** From 99788b8236a068d4d4a5d74ed039cc443126fd19 Mon Sep 17 00:00:00 2001 From: Vadim Justus <v.justus@techdivision.com> Date: Mon, 8 Oct 2018 11:07:08 +0200 Subject: [PATCH 201/812] MSI-1735: Add @deprecation notice to all interfaces and extension points --- .../CatalogInventory/Api/Data/StockCollectionInterface.php | 3 +++ app/code/Magento/CatalogInventory/Api/Data/StockInterface.php | 3 +++ .../CatalogInventory/Api/Data/StockItemCollectionInterface.php | 3 +++ .../Magento/CatalogInventory/Api/Data/StockItemInterface.php | 3 +++ .../Api/Data/StockStatusCollectionInterface.php | 3 +++ .../Magento/CatalogInventory/Api/Data/StockStatusInterface.php | 3 +++ .../CatalogInventory/Api/RegisterProductSaleInterface.php | 3 +++ .../CatalogInventory/Api/RevertProductSaleInterface.php | 3 +++ .../CatalogInventory/Api/StockConfigurationInterface.php | 3 +++ .../Magento/CatalogInventory/Api/StockCriteriaInterface.php | 3 +++ app/code/Magento/CatalogInventory/Api/StockIndexInterface.php | 3 +++ .../CatalogInventory/Api/StockItemCriteriaInterface.php | 3 +++ .../CatalogInventory/Api/StockItemRepositoryInterface.php | 3 +++ .../Magento/CatalogInventory/Api/StockManagementInterface.php | 3 +++ .../Magento/CatalogInventory/Api/StockRegistryInterface.php | 3 +++ .../Magento/CatalogInventory/Api/StockRepositoryInterface.php | 3 +++ app/code/Magento/CatalogInventory/Api/StockStateInterface.php | 3 +++ .../CatalogInventory/Api/StockStatusCriteriaInterface.php | 3 +++ .../CatalogInventory/Api/StockStatusRepositoryInterface.php | 3 +++ .../CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php | 3 +++ .../CatalogInventory/Block/Adminhtml/Form/Field/Stock.php | 3 +++ app/code/Magento/CatalogInventory/Block/Qtyincrements.php | 3 +++ .../CatalogInventory/Block/Stockqty/DefaultStockqty.php | 3 +++ app/code/Magento/CatalogInventory/Helper/Stock.php | 3 +++ .../Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php | 3 +++ .../CatalogInventory/Model/Quote/Item/QuantityValidator.php | 3 +++ .../Model/ResourceModel/Indexer/Stock/DefaultStock.php | 3 +++ .../ResourceModel/Indexer/Stock/QueryProcessorInterface.php | 3 +++ .../Model/ResourceModel/Indexer/Stock/StockInterface.php | 3 +++ .../Model/ResourceModel/Indexer/StockFactory.php | 3 +++ .../CatalogInventory/Model/ResourceModel/Stock/Status.php | 3 +++ app/code/Magento/CatalogInventory/Model/Source/Backorders.php | 3 +++ app/code/Magento/CatalogInventory/Model/Source/Stock.php | 3 +++ app/code/Magento/CatalogInventory/composer.json | 3 ++- 34 files changed, 101 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php index c2521f77ca24a..a0f06cd406b14 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php @@ -15,6 +15,9 @@ * Interface StockCollectionInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockCollectionInterface extends SearchResultsInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php index 53e95921ea955..2bc9b474ff298 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php @@ -11,6 +11,9 @@ * Interface Stock * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockInterface extends ExtensibleDataInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php index 038174c8e52be..dbb8602678d80 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php @@ -15,6 +15,9 @@ * Interface StockItemCollectionInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockItemCollectionInterface extends SearchResultsInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php index b876615468ba9..2daebf96c6c02 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php @@ -11,6 +11,9 @@ * Interface StockItem * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockItemInterface extends ExtensibleDataInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php index 70a2c29ff9a6e..35959017606ad 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php @@ -11,6 +11,9 @@ * Stock Status collection interface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockStatusCollectionInterface extends SearchResultsInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php index c9ae6a96a3671..397048cb04628 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php @@ -11,6 +11,9 @@ * Interface StockStatusInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockStatusInterface extends ExtensibleDataInterface { diff --git a/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php b/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php index 9122fb0038646..2f2b97bf1fa93 100644 --- a/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php +++ b/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php @@ -12,6 +12,9 @@ /** * @api + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface RegisterProductSaleInterface { diff --git a/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php b/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php index ed496f3882fc2..0f441ee6268a1 100644 --- a/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php +++ b/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php @@ -9,6 +9,9 @@ /** * @api + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface RevertProductSaleInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php b/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php index a23d5030b8242..be815c3145607 100644 --- a/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php @@ -9,6 +9,9 @@ * Interface StockConfigurationInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockConfigurationInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php b/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php index 969af6481cb4a..d92d2931867bc 100644 --- a/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php @@ -9,6 +9,9 @@ * Interface StockCriteriaInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php b/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php index 1521b34c715b0..5a4c4b7ef52a1 100644 --- a/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php @@ -9,6 +9,9 @@ * Interface StockIndexInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockIndexInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php b/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php index a2fc7801b1d13..5d129c199fc8a 100644 --- a/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php @@ -9,6 +9,9 @@ * Interface StockItemCriteriaInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockItemCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php b/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php index 2732048d1445f..90f7d993e3607 100644 --- a/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php @@ -9,6 +9,9 @@ * Interface StockItemRepository * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockItemRepositoryInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php b/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php index ddb84abf3d1a5..dcd611a148398 100644 --- a/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php @@ -9,6 +9,9 @@ * Interface StockManagementInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockManagementInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php b/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php index 2d011e24f4105..7e3ee63d33aee 100644 --- a/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php @@ -9,6 +9,9 @@ * Interface StockRegistryInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockRegistryInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php b/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php index 80a7e79289cff..2b0c40582932d 100644 --- a/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php @@ -9,6 +9,9 @@ * Interface StockRepositoryInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockRepositoryInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockStateInterface.php b/app/code/Magento/CatalogInventory/Api/StockStateInterface.php index 8a1f7da5158ed..49cc746e79d39 100644 --- a/app/code/Magento/CatalogInventory/Api/StockStateInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockStateInterface.php @@ -9,6 +9,9 @@ * Interface StockStateInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockStateInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php b/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php index e504e6355a15a..f57db6b2cef0a 100644 --- a/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php @@ -9,6 +9,9 @@ * Interface StockStatusCriteriaInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockStatusCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php b/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php index 94d4998c1e318..8be61afbbce11 100644 --- a/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php @@ -9,6 +9,9 @@ * Interface StockStatusRepositoryInterface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockStatusRepositoryInterface { diff --git a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php index 15dfbd122e950..38d3c33a9a1f8 100644 --- a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php +++ b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php @@ -10,6 +10,9 @@ * * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Minsaleqty extends \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray { diff --git a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php index 2c41e1798921a..74e062b7e07ca 100644 --- a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php +++ b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php @@ -14,6 +14,9 @@ /** * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Stock extends \Magento\Framework\Data\Form\Element\Select { diff --git a/app/code/Magento/CatalogInventory/Block/Qtyincrements.php b/app/code/Magento/CatalogInventory/Block/Qtyincrements.php index adaa762f3279b..9551e06264c1b 100644 --- a/app/code/Magento/CatalogInventory/Block/Qtyincrements.php +++ b/app/code/Magento/CatalogInventory/Block/Qtyincrements.php @@ -14,6 +14,9 @@ * * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Qtyincrements extends Template implements IdentityInterface { diff --git a/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php b/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php index c315338be0de0..cb8741c88b09d 100644 --- a/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php +++ b/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php @@ -11,6 +11,9 @@ * * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class DefaultStockqty extends AbstractStockqty implements \Magento\Framework\DataObject\IdentityInterface { diff --git a/app/code/Magento/CatalogInventory/Helper/Stock.php b/app/code/Magento/CatalogInventory/Helper/Stock.php index 494d440eeed89..eb76dd5fce057 100644 --- a/app/code/Magento/CatalogInventory/Helper/Stock.php +++ b/app/code/Magento/CatalogInventory/Helper/Stock.php @@ -18,6 +18,9 @@ * Class Stock * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Stock { diff --git a/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php index 36721db874887..29f7aa61ab8b1 100644 --- a/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php +++ b/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php @@ -20,6 +20,9 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Item extends \Magento\CatalogInventory\Model\Stock\Item implements IdentityInterface { diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php index b86c3cf13f31b..c13a2560c6ac2 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php @@ -25,6 +25,9 @@ * @api * @since 100.0.2 * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class QuantityValidator { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php index 366cb1c3902a3..ef43010826523 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php @@ -18,6 +18,9 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class DefaultStock extends AbstractIndexer implements StockInterface { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php index abe473bd9682b..a24a10d7433c2 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php @@ -11,6 +11,9 @@ /** * @api * @since 100.1.0 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface QueryProcessorInterface { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php index 5ced55edf208b..3f0523e8fba6c 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php @@ -9,6 +9,9 @@ * CatalogInventory Stock Indexer Interface * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ interface StockInterface { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php index f9738484766b9..fae1ee72ac34f 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php @@ -12,6 +12,9 @@ /** * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class StockFactory { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php index bc5fda4939adc..1e826ef229f13 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php @@ -13,6 +13,9 @@ * CatalogInventory Stock Status per website Resource Model * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/app/code/Magento/CatalogInventory/Model/Source/Backorders.php b/app/code/Magento/CatalogInventory/Model/Source/Backorders.php index 1d200d27a4445..b13f7e570d859 100644 --- a/app/code/Magento/CatalogInventory/Model/Source/Backorders.php +++ b/app/code/Magento/CatalogInventory/Model/Source/Backorders.php @@ -9,6 +9,9 @@ * Back orders source class * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Backorders implements \Magento\Framework\Option\ArrayInterface { diff --git a/app/code/Magento/CatalogInventory/Model/Source/Stock.php b/app/code/Magento/CatalogInventory/Model/Source/Stock.php index 9ed891d1dcc0f..992709419fa25 100644 --- a/app/code/Magento/CatalogInventory/Model/Source/Stock.php +++ b/app/code/Magento/CatalogInventory/Model/Source/Stock.php @@ -11,6 +11,9 @@ * CatalogInventory Stock source model * @api * @since 100.0.2 + * + * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) + * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html */ class Stock extends AbstractSource { diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json index 8b55b6f327988..007d744b2296f 100644 --- a/app/code/Magento/CatalogInventory/composer.json +++ b/app/code/Magento/CatalogInventory/composer.json @@ -27,5 +27,6 @@ "psr-4": { "Magento\\CatalogInventory\\": "" } - } + }, + "abandoned": "magento/inventory-composer-metapackage" } From 5f1b4014093e062169dd9597752eac1c970898e2 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 8 Oct 2018 14:10:04 +0300 Subject: [PATCH 202/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Block/DataProviders/ImageUploadConfig.php | 37 +++++++++++++++++++ .../Magento/Backend/Block/Media/Uploader.php | 10 ----- .../adminhtml/templates/media/uploader.phtml | 2 +- .../Product/Helper/Form/Gallery/Content.php | 20 ++++++++-- .../layout/cms_wysiwyg_images_index.xml | 6 ++- .../templates/browser/content/uploader.phtml | 6 +-- 6 files changed, 63 insertions(+), 18 deletions(-) create mode 100644 app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php diff --git a/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php b/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php new file mode 100644 index 0000000000000..1ba3daf35d2cf --- /dev/null +++ b/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Backend\Block\DataProviders; + +use Magento\Framework\View\Element\Block\ArgumentInterface; +use Magento\Backend\Model\Image\ImageUploadConfigInterface; + +/** + * Provides additional data for image uploader + */ +class ImageUploadConfig implements ArgumentInterface +{ + /** + * @var ImageUploadConfigInterface + */ + private $imageUploadConfig; + + public function __construct(ImageUploadConfigInterface $imageUploadConfig) + { + $this->imageUploadConfig = $imageUploadConfig; + } + + /** + * Get image resize configuration + * + * @return int + */ + public function getIsResizeEnabled(): int + { + return (int)$this->imageUploadConfig->isResizeEnabled(); + } +} diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php index 22e9197418e4c..c332c91b54b27 100644 --- a/app/code/Magento/Backend/Block/Media/Uploader.php +++ b/app/code/Magento/Backend/Block/Media/Uploader.php @@ -127,16 +127,6 @@ public function getImageUploadMaxHeight() return $this->imageUploadConfig->getMaxHeight(); } - /** - * Get image resize configuration - * - * @return int - */ - public function getIsResizeEnabled(): int - { - return (int)$this->imageUploadConfig->isResizeEnabled(); - } - /** * Prepares layout and set element renderer * diff --git a/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml b/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml index d6e97cf4d58e3..4d9ba6a8c4bad 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/media/uploader.phtml @@ -15,7 +15,7 @@ "maxFileSize": <?= /* @escapeNotVerified */ $block->getFileSizeService()->getMaxFileSize() ?>, "maxWidth": <?= /* @escapeNotVerified */ $block->getImageUploadMaxWidth() ?>, "maxHeight": <?= /* @escapeNotVerified */ $block->getImageUploadMaxHeight() ?>, - "isResizeEnabled": <?= /* @noEscape */ $block->getIsResizeEnabled() ?> + "isResizeEnabled": <?= /* @noEscape */ $block->getImageUploadConfigData()->getIsResizeEnabled() ?> } }' > diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index e1208e25cc7c8..d9e343fd2b3f0 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -13,11 +13,12 @@ */ namespace Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Gallery; +use Magento\Framework\App\ObjectManager; use Magento\Backend\Block\Media\Uploader; use Magento\Framework\View\Element\AbstractBlock; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\FileSystemException; - +use Magento\Backend\Block\DataProviders\ImageUploadConfig as ImageUploadConfigDataProvider; /** * Block for gallery content. */ @@ -43,21 +44,30 @@ class Content extends \Magento\Backend\Block\Widget */ private $imageHelper; + /** + * @var ImageUploadConfigDataProvider + */ + private $imageUploadConfigDataProvider; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder * @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig * @param array $data + * @param ImageUploadConfigDataProvider $imageUploadConfigDataProvider */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Framework\Json\EncoderInterface $jsonEncoder, \Magento\Catalog\Model\Product\Media\Config $mediaConfig, - array $data = [] + array $data = [], + ImageUploadConfigDataProvider $imageUploadConfigDataProvider = null ) { $this->_jsonEncoder = $jsonEncoder; $this->_mediaConfig = $mediaConfig; parent::__construct($context, $data); + $this->imageUploadConfigDataProvider = $imageUploadConfigDataProvider + ?: ObjectManager::getInstance()->get(ImageUploadConfigDataProvider::class); } /** @@ -67,7 +77,11 @@ public function __construct( */ protected function _prepareLayout() { - $this->addChild('uploader', \Magento\Backend\Block\Media\Uploader::class); + $this->addChild( + 'uploader', + \Magento\Backend\Block\Media\Uploader::class, + ['image_upload_config_data' => $this->imageUploadConfigDataProvider] + ); $this->getUploader()->getConfig()->setUrl( $this->_urlBuilder->addSessionParam()->getUrl('catalog/product_gallery/upload') diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_wysiwyg_images_index.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_wysiwyg_images_index.xml index 1bc8828ef6c8e..6703b6c277123 100644 --- a/app/code/Magento/Cms/view/adminhtml/layout/cms_wysiwyg_images_index.xml +++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_wysiwyg_images_index.xml @@ -9,7 +9,11 @@ <container name="root"> <block class="Magento\Cms\Block\Adminhtml\Wysiwyg\Images\Content" name="wysiwyg_images.content" template="Magento_Cms::browser/content.phtml"> <block class="Magento\Cms\Block\Adminhtml\Wysiwyg\Images\Tree" name="wysiwyg_images.tree" template="Magento_Cms::browser/tree.phtml"/> - <block class="Magento\Cms\Block\Adminhtml\Wysiwyg\Images\Content\Uploader" name="wysiwyg_images.uploader" template="Magento_Cms::browser/content/uploader.phtml"/> + <block class="Magento\Cms\Block\Adminhtml\Wysiwyg\Images\Content\Uploader" name="wysiwyg_images.uploader" template="Magento_Cms::browser/content/uploader.phtml"> + <arguments> + <argument name="image_upload_config_data" xsi:type="object">Magento\Backend\Block\DataProviders\ImageUploadConfig</argument> + </arguments> + </block> </block> </container> </layout> diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml index b1824f639c940..c6810f774238c 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml @@ -17,11 +17,11 @@ foreach ($filters as $media_type) { }, $media_type['files'])); } -$resizeConfig = ($block->getIsResizeEnabled()) +$resizeConfig = ($block->getImageUploadConfigData()->getIsResizeEnabled()) ? "{action: 'resize', maxWidth: " - . $block->getImageUploadMaxWidth() + . $block->escapeHtml($block->getImageUploadMaxWidth()) . ", maxHeight: " - . $block->getImageUploadMaxHeight() + . $block->escapeHtml($block->getImageUploadMaxHeight()) . "}" : "{action: 'resize'}"; ?> From d921849d060864994249f387487d743dce85fc06 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Mon, 8 Oct 2018 14:12:59 +0300 Subject: [PATCH 203/812] MAGETWO-91517: Cancel and Return link removes billing and shipping address - Fix statics. --- .../view/frontend/web/js/model/checkout-data-resolver.js | 1 + .../Checkout/view/frontend/web/js/view/form/element/email.js | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 4abb4c4d61700..cd4c59df51187 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -75,6 +75,7 @@ define([ } newCustomerShippingAddress = checkoutData.getNewCustomerShippingAddress(); + if (newCustomerShippingAddress) { createShippingAddress(newCustomerShippingAddress); } diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js index 37a785e292365..4d883fb1373bd 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js @@ -27,6 +27,7 @@ define([ } validatedEmail = checkoutData.getValidatedEmailValue(); + if (validatedEmail && !customer.isLoggedIn()) { quote.guestEmail = validatedEmail; } From e258878dbf07fcb14449b8253adb2f8f35b6ebcf Mon Sep 17 00:00:00 2001 From: Valentin Boyanov <val.rusev@gmail.com> Date: Mon, 8 Oct 2018 14:02:48 +0200 Subject: [PATCH 204/812] MAGETWO-34709 Changing empty label value for first option. --- app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php b/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php index dc928b4c7942d..4f4ed9de03e43 100644 --- a/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php +++ b/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php @@ -250,7 +250,7 @@ protected function _getSelectHtmlWithValue(Attribute $attribute, $value) if ('' === $firstOption['value']) { $options[key($options)]['label'] = ''; } else { - array_unshift($options, ['value' => '', 'label' => '']); + array_unshift($options, ['value' => '', 'label' => __('-- Not Selected --')]); } $arguments = [ 'name' => $this->getFilterElementName($attribute->getAttributeCode()), From 1b03c19021957d85e625eeb5bb61cd3921b31937 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 8 Oct 2018 09:16:07 -0300 Subject: [PATCH 205/812] Revert back change --- app/code/Magento/Newsletter/Model/Queue.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/Queue.php b/app/code/Magento/Newsletter/Model/Queue.php index 67f8cadbfaed4..efb68fd4243d1 100644 --- a/app/code/Magento/Newsletter/Model/Queue.php +++ b/app/code/Magento/Newsletter/Model/Queue.php @@ -196,8 +196,7 @@ public function setQueueStartAtByString($startAt) if ($startAt === null || $startAt == '') { $this->setQueueStartAt(null); } else { - $startAt = $this->timezone->convertConfigTimeToUtcWithPattern($startAt, 'Y-m-d H:i:s', null); - $this->setQueueStartAt($startAt); + $this->setQueueStartAt($this->timezone->convertConfigTimeToUtc($startAt)); } return $this; } From c6c2ffe214f45366e81e3644b7ddadb2b2fce383 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 8 Oct 2018 09:17:39 -0300 Subject: [PATCH 206/812] Rever-back unit test --- .../Test/Unit/DateTime/TimezoneTest.php | 29 ++----------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php index ea761db902674..d57525590b9e8 100644 --- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php +++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php @@ -124,15 +124,11 @@ public function dateIncludeTimeDataProvider() * @param string $expectedResult * @dataProvider getConvertConfigTimeToUtcFixtures */ - public function testConvertConfigTimeToUtc($date, $configuredTimezone, $configuredLocale, $expectedResult) + public function testConvertConfigTimeToUtc($date, $configuredTimezone, $expectedResult) { - $this->localeResolver - ->method('getLocale') - ->willReturn($configuredLocale); - $this->scopeConfigWillReturnConfiguredTimezone($configuredTimezone); - $this->assertEquals($expectedResult, $this->getTimezone()->convertConfigTimeToUtcWithPattern($date)); + $this->assertEquals($expectedResult, $this->getTimezone()->convertConfigTimeToUtc($date)); } /** @@ -145,37 +141,16 @@ public function getConvertConfigTimeToUtcFixtures() 'string' => [ '2016-10-10 10:00:00', 'UTC', - null, '2016-10-10 10:00:00' ], - 'string-en_US' => [ - 'Sep 29, 2018, 6:07:38 PM', - 'UTC', - 'en_US', - '2018-09-29 18:07:38' - ], - 'string-pt_BR' => [ - '29 de set de 2018 18:07:38', - 'UTC', - 'pt_BR', - '2018-09-29 18:07:38' - ], - 'string-tr_TR' => [ - '29 Eyl 2018 18:07:38', - 'UTC', - 'tr_TR', - '2018-09-29 18:07:38' - ], 'datetime' => [ new \DateTime('2016-10-10 10:00:00', new \DateTimeZone('UTC')), 'UTC', - null, '2016-10-10 10:00:00' ], 'datetimeimmutable' => [ new \DateTimeImmutable('2016-10-10 10:00:00', new \DateTimeZone('UTC')), 'UTC', - null, '2016-10-10 10:00:00' ] ]; From cc16df90455a510083f4d4bebda27566c23e221e Mon Sep 17 00:00:00 2001 From: Thiago Lima <thiagolimaufrj@gmail.com> Date: Mon, 8 Oct 2018 14:27:56 +0200 Subject: [PATCH 207/812] fix issue Fatal Error when save configurable product in Magento 2.2.5 #18082 --- .../Product/Initialization/Helper/Plugin/Configurable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php index 5cd8b6a7d0b95..556939ec112f1 100644 --- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php @@ -158,7 +158,7 @@ protected function getVariationMatrix() $configurableMatrix = json_decode($configurableMatrix, true); foreach ($configurableMatrix as $item) { - if ($item['newProduct']) { + if (isset($item['newProduct'])) { $result[$item['variationKey']] = $this->mapData($item); if (isset($item['qty'])) { From 502e5ac6941a10e39ef1e559c91565bdb07a4d14 Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 8 Oct 2018 09:34:26 -0300 Subject: [PATCH 208/812] New class and interface created for time format convertion --- app/code/Magento/Store/etc/di.xml | 6 ++ app/etc/di.xml | 1 + .../Timezone/LocalizedDateToUtcConverter.php | 86 +++++++++++++++++++ .../LocalizedDateToUtcConverterInterface.php | 17 ++++ 4 files changed, 110 insertions(+) create mode 100644 lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php create mode 100644 lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml index be005264b7bbf..f9e003aca69af 100644 --- a/app/code/Magento/Store/etc/di.xml +++ b/app/code/Magento/Store/etc/di.xml @@ -294,6 +294,12 @@ <argument name="scopeType" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument> </arguments> </type> + <type name="Magento\Framework\Stdlib\DateTime\Timezone\LocalizedDateToUtcConverter"> + <arguments> + <argument name="defaultTimezonePath" xsi:type="const">Magento\Directory\Helper\Data::XML_PATH_DEFAULT_TIMEZONE</argument> + <argument name="scopeType" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument> + </arguments> + </type> <type name="Magento\Framework\Locale\Resolver"> <arguments> <argument name="defaultLocalePath" xsi:type="const">Magento\Directory\Helper\Data::XML_PATH_DEFAULT_LOCALE</argument> diff --git a/app/etc/di.xml b/app/etc/di.xml index db979f9b76382..282a0af4f46a5 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -146,6 +146,7 @@ <preference for="Magento\Framework\Locale\FormatInterface" type="Magento\Framework\Locale\Format" /> <preference for="Magento\Framework\Locale\ResolverInterface" type="Magento\Framework\Locale\Resolver" /> <preference for="Magento\Framework\Stdlib\DateTime\TimezoneInterface" type="Magento\Framework\Stdlib\DateTime\Timezone" /> + <preference for="Magento\Framework\Stdlib\DateTime\Timezone\LocalizedDateToUtcConverterInterface" type="Magento\Framework\Stdlib\DateTime\Timezone\LocalizedDateToUtcConverter" /> <preference for="Magento\Framework\Communication\ConfigInterface" type="Magento\Framework\Communication\Config" /> <preference for="Magento\Framework\Module\ResourceInterface" type="Magento\Framework\Module\ModuleResource" /> <preference for="Magento\Framework\Pricing\Amount\AmountInterface" type="Magento\Framework\Pricing\Amount\Base" /> diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php new file mode 100644 index 0000000000000..23dadc11cc6ef --- /dev/null +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Stdlib\DateTime\Timezone; + +use Magento\Framework\Locale\ResolverInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; + +/** + * Class LocalizedDateToUtcConverter + */ +class LocalizedDateToUtcConverter implements LocalizedDateToUtcConverterInterface +{ + /** + * Contains default date format + * + * @var string + */ + private $defaultFormat = 'Y-m-d H:i:s'; + + /** + * @var ResolverInterface + */ + private $localeResolver; + + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + + /** + * @var string + */ + private $scopeType; + + /** + * @var string + */ + private $defaultTimezonePath; + + /** + * LocalizedDateToUtcConverter constructor. + * + * @param ResolverInterface $localeResolver + */ + public function __construct( + ResolverInterface $localeResolver, + ScopeConfigInterface $scopeConfig, + $scopeType, + $defaultTimezonePath + ) + { + $this->localeResolver = $localeResolver; + $this->scopeConfig = $scopeConfig; + $this->scopeType = $scopeType; + $this->defaultTimezonePath = $defaultTimezonePath; + } + + /** + * @inheritdoc + */ + public function convertLocalizedDateToUtc($date) + { + $locale = $this->localeResolver->getLocale(); + $formatter = new \IntlDateFormatter( + $locale, + \IntlDateFormatter::MEDIUM, + \IntlDateFormatter::MEDIUM, + $this->getConfigTimezone(), + null, + null + ); + $unixTime = $formatter->parse($date); + $dateTime = new DateTime($this); + $dateUniversal = $dateTime->gmtDate(null, $unixTime); + $date = new \DateTime($dateUniversal, new \DateTimeZone($this->getConfigTimezone())); + + $date->setTimezone(new \DateTimeZone('UTC')); + + return $date->format($this->defaultFormat); + } +} \ No newline at end of file diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php new file mode 100644 index 0000000000000..277900c46badf --- /dev/null +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php @@ -0,0 +1,17 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Stdlib\DateTime\Timezone; + +interface LocalizedDateToUtcConverterInterface +{ + /** + * @param string $data + * @return string + */ + public function convertLocalizedDateToUtc($date); +} \ No newline at end of file From 51e8fe7118e6734e3ee250483d9877eda2d1388a Mon Sep 17 00:00:00 2001 From: Bunyamin <inanbunyamin90@gmail.com> Date: Mon, 8 Oct 2018 10:07:17 -0300 Subject: [PATCH 209/812] Convert local timestamp into GMT timestamp --- app/code/Magento/Newsletter/Model/Queue.php | 18 +++++--- app/code/Magento/Store/etc/di.xml | 6 --- .../Timezone/LocalizedDateToUtcConverter.php | 44 +++++++------------ 3 files changed, 29 insertions(+), 39 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/Queue.php b/app/code/Magento/Newsletter/Model/Queue.php index efb68fd4243d1..58c5ba8a7e04a 100644 --- a/app/code/Magento/Newsletter/Model/Queue.php +++ b/app/code/Magento/Newsletter/Model/Queue.php @@ -7,6 +7,7 @@ use Magento\Framework\App\TemplateTypesInterface; use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Framework\Stdlib\DateTime\Timezone\LocalizedDateToUtcConverterInterface; /** * Newsletter queue model. @@ -117,6 +118,11 @@ class Queue extends \Magento\Framework\Model\AbstractModel implements TemplateTy */ private $timezone; + /** + * @var LocalizedDateToUtcConverterInterface + */ + private $utcConverter; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -144,7 +150,8 @@ public function __construct( \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], - TimezoneInterface $timezone = null + TimezoneInterface $timezone = null, + LocalizedDateToUtcConverterInterface $utcConverter = null ) { parent::__construct( $context, @@ -159,9 +166,10 @@ public function __construct( $this->_problemFactory = $problemFactory; $this->_subscribersCollection = $subscriberCollectionFactory->create(); $this->_transportBuilder = $transportBuilder; - $this->timezone = $timezone ?: \Magento\Framework\App\ObjectManager::getInstance()->get( - TimezoneInterface::class - ); + + $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); + $this->timezone = $timezone ?: $objectManager->get(TimezoneInterface::class); + $this->utcConverter = $utcConverter ?? $objectManager->get(LocalizedDateToUtcConverterInterface::class); } /** @@ -196,7 +204,7 @@ public function setQueueStartAtByString($startAt) if ($startAt === null || $startAt == '') { $this->setQueueStartAt(null); } else { - $this->setQueueStartAt($this->timezone->convertConfigTimeToUtc($startAt)); + $this->setQueueStartAt($this->utcConverter->convertLocalizedDateToUtc($startAt)); } return $this; } diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml index f9e003aca69af..be005264b7bbf 100644 --- a/app/code/Magento/Store/etc/di.xml +++ b/app/code/Magento/Store/etc/di.xml @@ -294,12 +294,6 @@ <argument name="scopeType" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument> </arguments> </type> - <type name="Magento\Framework\Stdlib\DateTime\Timezone\LocalizedDateToUtcConverter"> - <arguments> - <argument name="defaultTimezonePath" xsi:type="const">Magento\Directory\Helper\Data::XML_PATH_DEFAULT_TIMEZONE</argument> - <argument name="scopeType" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument> - </arguments> - </type> <type name="Magento\Framework\Locale\Resolver"> <arguments> <argument name="defaultLocalePath" xsi:type="const">Magento\Directory\Helper\Data::XML_PATH_DEFAULT_LOCALE</argument> diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php index 23dadc11cc6ef..721ed9a384dad 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php @@ -7,6 +7,7 @@ namespace Magento\Framework\Stdlib\DateTime\Timezone; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; use Magento\Framework\Locale\ResolverInterface; use Magento\Framework\App\Config\ScopeConfigInterface; @@ -23,24 +24,14 @@ class LocalizedDateToUtcConverter implements LocalizedDateToUtcConverterInterfac private $defaultFormat = 'Y-m-d H:i:s'; /** - * @var ResolverInterface - */ - private $localeResolver; - - /** - * @var ScopeConfigInterface - */ - private $scopeConfig; - - /** - * @var string + * @var TimezoneInterface */ - private $scopeType; + private $timezone; /** - * @var string + * @var ResolverInterface */ - private $defaultTimezonePath; + private $localeResolver; /** * LocalizedDateToUtcConverter constructor. @@ -48,16 +39,12 @@ class LocalizedDateToUtcConverter implements LocalizedDateToUtcConverterInterfac * @param ResolverInterface $localeResolver */ public function __construct( - ResolverInterface $localeResolver, - ScopeConfigInterface $scopeConfig, - $scopeType, - $defaultTimezonePath + TimezoneInterface $timezone, + ResolverInterface $localeResolver ) { + $this->timezone = $timezone; $this->localeResolver = $localeResolver; - $this->scopeConfig = $scopeConfig; - $this->scopeType = $scopeType; - $this->defaultTimezonePath = $defaultTimezonePath; } /** @@ -65,20 +52,21 @@ public function __construct( */ public function convertLocalizedDateToUtc($date) { + $configTimezone = $this->timezone->getConfigTimezone(); $locale = $this->localeResolver->getLocale(); + $formatter = new \IntlDateFormatter( $locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::MEDIUM, - $this->getConfigTimezone(), - null, - null + $configTimezone ); - $unixTime = $formatter->parse($date); - $dateTime = new DateTime($this); - $dateUniversal = $dateTime->gmtDate(null, $unixTime); - $date = new \DateTime($dateUniversal, new \DateTimeZone($this->getConfigTimezone())); + $localTimestamp = $formatter->parse($date); + $gmtTimestamp = $this->timezone->date($localTimestamp)->getTimestamp(); + $formattedUniversalTime = date($this->defaultFormat, $gmtTimestamp); + + $date = new \DateTime($formattedUniversalTime, new \DateTimeZone($configTimezone)); $date->setTimezone(new \DateTimeZone('UTC')); return $date->format($this->defaultFormat); From 9d824af97af6d6ac34cf18b1c6086dc59ba58cdc Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Mon, 8 Oct 2018 16:39:07 +0300 Subject: [PATCH 210/812] ENGCOM-2998: Adding trimming sku value function to sku backend model. #18019. Fix static tests. --- .../Catalog/Model/Product/Attribute/Backend/Sku.php | 10 +++++----- .../Ui/DataProvider/Product/Form/Modifier/General.php | 10 ++++++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php index 2ea3b9aaf10a8..98738e055ca8f 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php @@ -4,15 +4,13 @@ * See COPYING.txt for license details. */ -/** - * Catalog product SKU backend attribute model - * - * @author Magento Core Team <core@magentocommerce.com> - */ namespace Magento\Catalog\Model\Product\Attribute\Backend; use Magento\Catalog\Model\Product; +/** + * Catalog product SKU backend attribute model. + */ class Sku extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend { /** @@ -130,6 +128,8 @@ protected function _getLastSimilarAttributeValueIncrement($attribute, $object) } /** + * Remove extra spaces from attribute value before save. + * * @param Product $object * @return void */ diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php index e0b0d066c1c1d..6ec1cc6c46d9d 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php @@ -58,8 +58,11 @@ public function __construct( } /** - * {@inheritdoc} + * Customize number fields for advanced price and weight fields. + * * @since 101.0.0 + * @param array $data + * @return array * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function modifyData(array $data) @@ -130,8 +133,11 @@ protected function customizeAdvancedPriceFormat(array $data) } /** - * {@inheritdoc} + * Customize product form fields. + * * @since 101.0.0 + * @param array $meta + * @return array */ public function modifyMeta(array $meta) { From b56aa55af499883d9c61aab7f86495d9dd2400c4 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Mon, 8 Oct 2018 17:45:30 +0300 Subject: [PATCH 211/812] MAGETWO-81469: Cached Config is Different From DB --- .../Test/Unit/App/Config/Type/SystemTest.php | 181 ------------------ 1 file changed, 181 deletions(-) delete mode 100644 app/code/Magento/Config/Test/Unit/App/Config/Type/SystemTest.php diff --git a/app/code/Magento/Config/Test/Unit/App/Config/Type/SystemTest.php b/app/code/Magento/Config/Test/Unit/App/Config/Type/SystemTest.php deleted file mode 100644 index 40aa110382ede..0000000000000 --- a/app/code/Magento/Config/Test/Unit/App/Config/Type/SystemTest.php +++ /dev/null @@ -1,181 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Config\Test\Unit\App\Config\Type; - -use Magento\Config\App\Config\Type\System; -use Magento\Framework\App\Config\ConfigSourceInterface; -use Magento\Framework\App\Config\Spi\PostProcessorInterface; -use Magento\Framework\App\Config\Spi\PreProcessorInterface; -use Magento\Framework\Cache\FrontendInterface; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\Store\Model\Config\Processor\Fallback; -use Magento\Config\App\Config\Type\System\Reader; - -/** - * Test how Class process source, cache them and retrieve value by path - * @package Magento\Config\Test\Unit\App\Config\Type - */ -class SystemTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var ConfigSourceInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $source; - - /** - * @var PostProcessorInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $postProcessor; - - /** - * @var PreProcessorInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $preProcessor; - - /** - * @var Fallback|\PHPUnit_Framework_MockObject_MockObject - */ - private $fallback; - - /** - * @var FrontendInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $cache; - - /** - * @var System - */ - private $configType; - - /** - * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $serializer; - - /** - * @var Reader|\PHPUnit_Framework_MockObject_MockObject - */ - private $reader; - - public function setUp() - { - $this->source = $this->getMockBuilder(ConfigSourceInterface::class) - ->getMockForAbstractClass(); - $this->postProcessor = $this->getMockBuilder(PostProcessorInterface::class) - ->getMockForAbstractClass(); - $this->fallback = $this->getMockBuilder(Fallback::class) - ->disableOriginalConstructor() - ->getMock(); - $this->cache = $this->getMockBuilder(FrontendInterface::class) - ->getMockForAbstractClass(); - $this->preProcessor = $this->getMockBuilder(PreProcessorInterface::class) - ->getMockForAbstractClass(); - $this->serializer = $this->getMockBuilder(SerializerInterface::class) - ->getMock(); - $this->reader = $this->getMockBuilder(Reader::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->configType = new System( - $this->source, - $this->postProcessor, - $this->fallback, - $this->cache, - $this->serializer, - $this->preProcessor, - 1, - 'system', - $this->reader - ); - } - - public function testGetCachedWithLoadDefaultScopeData() - { - $path = 'default/dev/unsecure/url'; - $url = 'http://magento.test/'; - $data = [ - 'dev' => [ - 'unsecure' => [ - 'url' => $url - ] - ] - ]; - - $this->cache->expects($this->any()) - ->method('load') - ->willReturnOnConsecutiveCalls('1', serialize($data)); - $this->serializer->expects($this->once()) - ->method('unserialize') - ->willReturn($data); - $this->assertEquals($url, $this->configType->get($path)); - } - - public function testGetCachedWithLoadAllData() - { - $url = 'http://magento.test/'; - $data = [ - 'dev' => [ - 'unsecure' => [ - 'url' => $url - ] - ] - ]; - - $this->cache->expects($this->any()) - ->method('load') - ->willReturnOnConsecutiveCalls('1', serialize($data)); - $this->serializer->expects($this->once()) - ->method('unserialize') - ->willReturn($data); - $this->assertEquals($data, $this->configType->get('')); - } - - public function testGetNotCached() - { - $path = 'stores/default/dev/unsecure/url'; - $url = 'http://magento.test/'; - - $dataToCache = [ - 'unsecure' => [ - 'url' => $url - ] - ]; - $data = [ - 'default' => [], - 'websites' => [], - 'stores' => [ - 'default' => [ - 'dev' => [ - 'unsecure' => [ - 'url' => $url - ] - ] - ] - ] - ]; - $this->cache->expects($this->any()) - ->method('load') - ->willReturnOnConsecutiveCalls(false, false); - - $this->serializer->expects($this->atLeastOnce()) - ->method('serialize') - ->willReturn(serialize($dataToCache)); - $this->cache->expects($this->atLeastOnce()) - ->method('save') - ->willReturnSelf(); - $this->reader->expects($this->once()) - ->method('read') - ->willReturn($data); - $this->postProcessor->expects($this->once()) - ->method('process') - ->with($data) - ->willReturn($data); - - $this->assertEquals($url, $this->configType->get($path)); - $this->assertEquals($url, $this->configType->get($path)); - } -} From eb2dd92bfab57e45a50b60f7d29adb80bff27c38 Mon Sep 17 00:00:00 2001 From: Nikita Chubukov <nikita_chubukov@epam.com> Date: Mon, 8 Oct 2018 19:19:25 +0300 Subject: [PATCH 212/812] MAGETWO-91651: Navigation Menu problem on Mobile theme - Added scroll to top menu items --- lib/web/mage/menu.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/web/mage/menu.js b/lib/web/mage/menu.js index b8000640506f1..7096c4ecb7d6d 100644 --- a/lib/web/mage/menu.js +++ b/lib/web/mage/menu.js @@ -439,6 +439,7 @@ define([ event.preventDefault(); target = $(event.target).closest('.ui-menu-item'); + target.get(0).scrollIntoView(); if (!target.hasClass('level-top') || !target.has('.ui-menu').length) { window.location.href = target.find('> a').attr('href'); From 40c809f0d82e6bdd49f8624c42907d451f6924fb Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 8 Oct 2018 15:28:28 -0500 Subject: [PATCH 213/812] MAGETWO-94962: Unable to set default option for swatch attribute --- .../AdminCreateProductAttributeSection.xml | 3 + .../AdminProductAttributeOptionsSection.xml | 14 ++++ ...dminCreateDropdownProductAttributeTest.xml | 74 +++++++++++++++++++ .../Mftf/Section/AdminManageSwatchSection.xml | 1 + ...ateVisualSwatchWithNonValidOptionsTest.xml | 39 +++++++++- 5 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml index 17778c76da9b9..78d06afa7f003 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml @@ -23,6 +23,9 @@ <element name="checkIfTabOpen" selector="//div[@id='advanced_fieldset-wrapper' and not(contains(@class,'opened'))]" type="button"/> <element name="useInLayeredNavigation" type="select" selector="#is_filterable"/> </section> + <section name="AttributeOptionsSection"> + <element name="AddOption" type="button" selector="#add_new_option_button"/> + </section> <section name="StorefrontPropertiesSection"> <element name="PageTitle" type="text" selector="//span[text()='Storefront Properties']" /> <element name="StoreFrontPropertiesTab" selector="#product_attribute_tabs_front" type="button"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml new file mode 100644 index 0000000000000..17ca306eeccfa --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="DropdownAttributeOptionsSection"> + <element name="nthAdminLabel" type="input" + selector="(//*[@id='manage-options-panel']//tr[{{var}}]//input[contains(@name, 'option[value]')])[1]" parameterized="true"/> + </section> +</sections> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml new file mode 100644 index 0000000000000..d9942e9fc1b46 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml @@ -0,0 +1,74 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateDropdownProductAttributeTest"> + <annotations> + <features value="Catalog"/> + <stories value="Create/configure Dropdown product attribute"/> + <title value="Admin should be able to create dropdown product attribute"/> + <description value="Admin should be able to create dropdown product attribute"/> + <severity value="BLOCKER"/> + <testCaseId value="MC-4140"/> + <group value="attribute"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + </before> + <after> + <!-- Remove attribute --> + <actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute"> + <argument name="ProductAttribute" value="productDropDownAttribute"/> + </actionGroup> + <click selector="{{AttributePropertiesSection.DeleteAttribute}}" stepKey="deleteAttribute"/> + + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <amOnPage url="{{ProductAttributePage.url}}" stepKey="navigateToNewProductAttributePage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + + <!-- Set attribute properties --> + <fillField selector="{{AttributePropertiesSection.DefaultLabel}}" + userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="fillDefaultLabel"/> + <selectOption selector="{{AttributePropertiesSection.InputType}}" + userInput="{{productDropDownAttribute.frontend_input}}" stepKey="fillInputType"/> + + <!-- Set advanced attribute properties --> + <click selector="{{AdvancedAttributePropertiesSection.AdvancedAttributePropertiesSectionToggle}}" + stepKey="showAdvancedAttributePropertiesSection"/> + <waitForElementVisible selector="{{AdvancedAttributePropertiesSection.AttributeCode}}" + stepKey="waitForSlideOut"/> + <fillField selector="{{AdvancedAttributePropertiesSection.AttributeCode}}" + userInput="{{productDropDownAttribute.attribute_code}}" + stepKey="fillAttributeCode"/> + + <!-- Add new attribute options --> + <click selector="{{AttributeOptionsSection.AddOption}}" stepKey="clickAddOption1"/> + <fillField selector="{{DropdownAttributeOptionsSection.nthAdminLabel('1')}}" + userInput="Fish and Chips" stepKey="fillAdminValue1"/> + + <click selector="{{AttributeOptionsSection.AddOption}}" stepKey="clickAddOption2"/> + <fillField selector="{{DropdownAttributeOptionsSection.nthAdminLabel('2')}}" + userInput="Fish & Chips" stepKey="fillAdminValue2"/> + + <!-- Save the new product attribute --> + <click selector="{{AttributePropertiesSection.Save}}" stepKey="clickSave1"/> + <waitForPageLoad stepKey="waitForGridPageLoad1"/> + <seeElement selector="{{AdminProductMessagesSection.successMessage}}" + stepKey="waitForSuccessMessage"/> + + <actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute"> + <argument name="ProductAttribute" value="productDropDownAttribute"/> + </actionGroup> + <!-- Check attribute data --> + <grabValueFrom selector="{{DropdownAttributeOptionsSection.nthAdminLabel('2')}}" + stepKey="secondOptionAdminLabel"/> + <assertEquals actual="$secondOptionAdminLabel" expected="Fish & Chips" + stepKey="assertSecondOption"/> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml index 25e03676f6870..6538af3178060 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml @@ -15,6 +15,7 @@ <element name="addSwatchText" type="button" selector="#add_new_swatch_text_option_button"/> <element name="swatchTextByIndex" type="input" selector="input[name='swatchtext[value][option_{{index}}][0]']" parameterized="true"/> <element name="nthSwatchText" type="input" selector="#swatch-text-options-panel table tbody tr:nth-of-type({{var}}) td:nth-of-type(3) input" parameterized="true"/> + <element name="nthIsDefault" type="input" selector="(//input[@name='defaultvisual[]'])[{{var}}]" parameterized="true"/> <element name="nthSwatchAdminDescription" type="input" selector="#swatch-text-options-panel table tbody tr:nth-of-type({{var}}) td:nth-of-type(4) input" parameterized="true"/> <!-- Selector for Admin Description input where the index is zero-based --> <element name="swatchAdminDescriptionByIndex" type="input" selector="input[name='optiontext[value][option_{{index}}][0]']" parameterized="true"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml index 50dcfbf3da090..5d174e71012fd 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml @@ -49,7 +49,7 @@ <!-- Add new swatch option without label --> <click selector="{{AdminManageSwatchSection.addSwatch}}" stepKey="clickAddSwatch1"/> - <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSwatch2"> + <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSwatch1"> <argument name="index" value="0"/> </actionGroup> <click selector="{{AdminManageSwatchSection.nthChooseColor('1')}}" stepKey="clickChooseColor1"/> @@ -66,6 +66,34 @@ <fillField selector="{{AdminManageSwatchSection.adminInputByIndex('0')}}" userInput="red" stepKey="fillAdmin1"/> + <!-- Add 2 additional new swatch options --> + <click selector="{{AdminManageSwatchSection.addSwatch}}" stepKey="clickAddSwatch2"/> + <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSwatch2"> + <argument name="index" value="1"/> + </actionGroup> + <click selector="{{AdminManageSwatchSection.nthChooseColor('2')}}" stepKey="clickChooseColor2"/> + <actionGroup ref="setColorPickerByHex" stepKey="fillHex2"> + <argument name="nthColorPicker" value="2"/> + <argument name="hexColor" value="00ff00"/> + </actionGroup> + <fillField selector="{{AdminManageSwatchSection.adminInputByIndex('1')}}" + userInput="green" stepKey="fillAdmin2"/> + + <click selector="{{AdminManageSwatchSection.addSwatch}}" stepKey="clickAddSwatch3"/> + <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSwatch3"> + <argument name="index" value="2"/> + </actionGroup> + <click selector="{{AdminManageSwatchSection.nthChooseColor('3')}}" stepKey="clickChooseColor3"/> + <actionGroup ref="setColorPickerByHex" stepKey="fillHex3"> + <argument name="nthColorPicker" value="3"/> + <argument name="hexColor" value="0000ff"/> + </actionGroup> + <fillField selector="{{AdminManageSwatchSection.adminInputByIndex('2')}}" + userInput="blue" stepKey="fillAdmin3"/> + + <!-- Mark second option as default --> + <click selector="{{AdminManageSwatchSection.nthIsDefault('2')}}" stepKey="setSecondOptionAsDefault"/> + <!-- Go to Storefront Properties tab --> <scrollToTopOfPage stepKey="scrollToTop"/> <click selector="{{StorefrontPropertiesSection.StoreFrontPropertiesTab}}" stepKey="goToStorefrontPropertiesTab"/> @@ -73,7 +101,14 @@ <!-- Save the new product attribute --> <click selector="{{AttributePropertiesSection.Save}}" stepKey="clickSave2"/> - <waitForElementVisible selector="{{AdminProductMessagesSection.successMessage}}" + <waitForPageLoad stepKey="waitForGridPageLoad"/> + <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="waitForSuccessMessage"/> + + <actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute"> + <argument name="ProductAttribute" value="visualSwatchAttribute"/> + </actionGroup> + <!-- Check attribute data --> + <seeCheckboxIsChecked selector="{{AdminManageSwatchSection.nthIsDefault('2')}}" stepKey="CheckDefaultOption"/> </test> </tests> \ No newline at end of file From 82df4f00588ded9c3aecdae744d7ecd76ebccc9f Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Mon, 8 Oct 2018 16:24:03 -0500 Subject: [PATCH 214/812] MAGETWO-71660: "Recently Ordered" widget conatins no more 5 products if qty of products > 5 --- app/code/Magento/Sales/Model/Order.php | 9 ++- .../CustomerData/LastOrderedItemsTest.php | 46 +++++++++++ ...with_customer_and_multiple_order_items.php | 12 +++ .../_files/order_with_multiple_items.php | 81 +++++++++++++++++++ 4 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 14c6154f0cb0a..ca8063aa57884 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -1337,7 +1337,10 @@ public function getParentItemsRandomCollection($limit = 1) */ protected function _getItemsRandomCollection($limit, $nonChildrenOnly = false) { - $collection = $this->_orderItemCollectionFactory->create()->setOrderFilter($this)->setRandomOrder(); + $collection = $this->_orderItemCollectionFactory->create() + ->setOrderFilter($this) + ->setRandomOrder() + ->setPageSize($limit); if ($nonChildrenOnly) { $collection->filterByParent(); @@ -1351,9 +1354,7 @@ protected function _getItemsRandomCollection($limit, $nonChildrenOnly = false) $products )->setVisibility( $this->_productVisibility->getVisibleInSiteIds() - )->addPriceData()->setPageSize( - $limit - )->load(); + )->addPriceData()->load(); foreach ($collection as $item) { $product = $productsCollection->getItemById($item->getProductId()); diff --git a/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php b/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php new file mode 100644 index 0000000000000..d0c2144c951e9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\CustomerData; + +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; +use Magento\Customer\Model\Session; + +/** + * @magentoAppIsolation enabled + */ +class LastOrderedItemsTest extends TestCase +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + public function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + } + + /** + * @magentoDataFixture Magento/Sales/_files/order_with_customer_and_multiple_order_items.php + */ + public function testDefaultFormatterIsAppliedWhenBasicIntegration() + { + /** @var Session $customerSession */ + $customerSession = $this->objectManager->get(Session::class); + $customerSession->loginById(1); + + /** @var LastOrderedItems $customerDataSectionSource */ + $customerDataSectionSource = $this->objectManager->get(LastOrderedItems::class); + $data = $customerDataSectionSource->getSectionData(); + $this->assertEquals( + LastOrderedItems::SIDEBAR_ORDER_LIMIT, + count($data['items']), + 'Section items count should not be greater then ' . LastOrderedItems::SIDEBAR_ORDER_LIMIT + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php new file mode 100644 index 0000000000000..06d3667f4d057 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php @@ -0,0 +1,12 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +include __DIR__ . '/order_with_multiple_items.php'; +include __DIR__ . '/../../../Magento/Customer/_files/customer.php'; + +$customerIdFromFixture = 1; +/** @var $order \Magento\Sales\Model\Order */ +$order->setCustomerId($customerIdFromFixture)->setCustomerIsGuest(false)->save(); diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php new file mode 100644 index 0000000000000..4fa84e4e28f01 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php @@ -0,0 +1,81 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'order.php'; +/** @var \Magento\Catalog\Model\Product $product */ +/** @var \Magento\Sales\Model\Order $order */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple.php'; +$orderItems[] = [ + 'product_id' => $product->getId(), + 'base_price' => 123, + 'order_id' => $order->getId(), + 'price' => 123, + 'row_total' => 126, + 'product_type' => 'simple' +]; + +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_duplicated.php'; +$orderItems[] = [ + 'product_id' => $product->getId(), + 'base_price' => 123, + 'order_id' => $order->getId(), + 'price' => 123, + 'row_total' => 126, + 'product_type' => 'simple' +]; + +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_with_full_option_set.php'; +$orderItems[] = [ + 'product_id' => $product->getId(), + 'base_price' => 123, + 'order_id' => $order->getId(), + 'price' => 123, + 'row_total' => 126, + 'product_type' => 'simple' +]; + +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_with_url_key.php'; +$orderItems[] = [ + 'product_id' => $product->getId(), + 'base_price' => 123, + 'order_id' => $order->getId(), + 'price' => 123, + 'row_total' => 126, + 'product_type' => 'simple' +]; + +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_with_all_fields.php'; +$orderItems[] = [ + 'product_id' => $product->getId(), + 'base_price' => 123, + 'order_id' => $order->getId(), + 'price' => 123, + 'row_total' => 126, + 'product_type' => 'simple' +]; + +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_with_custom_attribute.php'; +$orderItems[] = [ + 'product_id' => $product->getId(), + 'base_price' => 123, + 'order_id' => $order->getId(), + 'price' => 123, + 'row_total' => 126, + 'product_type' => 'simple' +]; + +/** @var array $orderItemData */ +foreach ($orderItems as $orderItemData) { + /** @var $orderItem \Magento\Sales\Model\Order\Item */ + $orderItem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\Order\Item::class + ); + $orderItem + ->setData($orderItemData) + ->save(); +} From fd226244e7350fd1ccad97c73ae53ff4d91dd706 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 8 Oct 2018 17:01:49 -0500 Subject: [PATCH 215/812] MAGETWO-94962: Unable to set default option for swatch attribute --- ...dminCreateDropdownProductAttributeTest.xml | 6 ++--- .../Catalog/view/adminhtml/web/js/options.js | 11 ++------ .../adminhtml/web/js/product-attributes.js | 13 +++------- .../Serialize/Serializer/FormData.php | 25 +------------------ 4 files changed, 9 insertions(+), 46 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml index d9942e9fc1b46..c3e0b22bc5afd 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml @@ -13,8 +13,8 @@ <title value="Admin should be able to create dropdown product attribute"/> <description value="Admin should be able to create dropdown product attribute"/> <severity value="BLOCKER"/> - <testCaseId value="MC-4140"/> - <group value="attribute"/> + <testCaseId value="MC-4982"/> + <group value="Catalog"/> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="login"/> @@ -68,7 +68,7 @@ <!-- Check attribute data --> <grabValueFrom selector="{{DropdownAttributeOptionsSection.nthAdminLabel('2')}}" stepKey="secondOptionAdminLabel"/> - <assertEquals actual="$secondOptionAdminLabel" expected="Fish & Chips" + <assertEquals actual="$secondOptionAdminLabel" expected="'Fish & Chips'" stepKey="assertSecondOption"/> </test> </tests> \ No newline at end of file diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index 24870a9e675f3..5a8dc1df86074 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -182,22 +182,15 @@ define([ }); } editForm.on('beforeSubmit', function () { - var optionsValues = [], - optionContainer = optionPanel.find('table tbody'); + var optionContainer = optionPanel.find('table tbody'); if (optionPanel.hasClass(activePanelClass)) { - optionContainer.find('input,select,textarea') - .serializeArray() - .map(function (el) { - optionsValues.push(el.name + '=' + el.value); - }); - jQuery('<input>') .attr({ type: 'hidden', name: 'serialized_options' }) - .val(JSON.stringify(optionsValues)) + .val(optionContainer.find('input, select, textarea').serialize()) .prependTo(editForm); } tableBody = optionContainer.detach(); diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index cf2b91e2df23b..2f8fcbdd7d40d 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -438,26 +438,19 @@ define([ .collapse('hide'); editForm.on('beforeSubmit', function () { - var swatchValues = [], - optionContainer; + var optionContainer; activePanel = swatchTextPanel.hasClass(activePanelClass) ? swatchTextPanel : swatchVisualPanel; optionContainer = activePanel.find('table tbody'); if (activePanel.hasClass(activePanelClass)) { - optionContainer - .find('input,select,textarea') - .serializeArray() - .map(function (el) { - swatchValues.push(el.name + '=' + el.value); - }); - $('<input>') .attr({ type: 'hidden', name: 'serialized_options' }) - .val(JSON.stringify(swatchValues)) + .val(optionContainer + .find('input, select, textarea').serialize()) .prependTo(editForm); } diff --git a/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php b/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php index a945822d92f97..b2597afdf92a5 100644 --- a/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php +++ b/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php @@ -13,19 +13,6 @@ */ class FormData { - /** - * @var Json - */ - private $serializer; - - /** - * @param Json $serializer - */ - public function __construct(Json $serializer) - { - $this->serializer = $serializer; - } - /** * Provides form data from the serialized data. * @@ -35,18 +22,8 @@ public function __construct(Json $serializer) */ public function unserialize(string $serializedData): array { - $encodedFields = $this->serializer->unserialize($serializedData); - - if (!is_array($encodedFields)) { - throw new \InvalidArgumentException('Unable to unserialize value.'); - } - $formData = []; - foreach ($encodedFields as $item) { - $decodedFieldData = []; - parse_str($item, $decodedFieldData); - $formData = array_replace_recursive($formData, $decodedFieldData); - } + parse_str($serializedData, $formData); return $formData; } From 02bdadd38cd023840ed85cca43b6091c3457d94a Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Tue, 9 Oct 2018 11:33:27 +0300 Subject: [PATCH 216/812] MAGETWO-91517: Cancel and Return link removes billing and shipping address - Fix statics. --- .../view/frontend/web/js/model/checkout-data-resolver.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index cd4c59df51187..1c2438889c170 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -214,6 +214,7 @@ define([ selectedBillingAddress = checkoutData.getSelectedBillingAddress(); newCustomerBillingAddressData = checkoutData.getNewCustomerBillingAddress(); + if (selectedBillingAddress) { if (selectedBillingAddress == 'new-customer-address' && newCustomerBillingAddressData) { //eslint-disable-line selectBillingAddress(createBillingAddress(newCustomerBillingAddressData)); From e819fc98e142b3f93a45cad3ae6ee061209265a5 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 9 Oct 2018 13:00:35 +0300 Subject: [PATCH 217/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Test/AdminSimpleProductImagesTest.xml | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml index 69931395a35d5..b10c8e5ad54a0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml @@ -87,10 +87,9 @@ <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorMedium"/> <!-- 10~ mb is allowed --> - <!-- Skipped MAGETWO-94092 --> - <!--<attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="large.jpg" stepKey="attachLarge"/> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="large.jpg" stepKey="attachLarge"/> <waitForPageLoad stepKey="waitForUploadLarge"/> - <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorLarge"/>--> + <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorLarge"/> <!-- *.gif is allowed --> <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="gif.gif" stepKey="attachGif"/> @@ -115,8 +114,7 @@ <!-- See all of the images that we uploaded --> <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('small')}}" stepKey="seeSmall"/> <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('medium')}}" stepKey="seeMedium"/> - <!-- Skipped MAGETWO-94092 --> - <!--<seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('large')}}" stepKey="seeLarge"/>--> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('large')}}" stepKey="seeLarge"/> <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('gif')}}" stepKey="seeGif"/> <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('jpg')}}" stepKey="seeJpg"/> <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('png')}}" stepKey="seePng"/> @@ -136,9 +134,9 @@ <!-- Upload an image --> <click selector="{{AdminProductImagesSection.productImagesToggle}}" stepKey="expandImages2"/> - <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="medium.jpg" stepKey="attachMedium2"/> - <waitForPageLoad stepKey="waitForUploadMedium2"/> - <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorMedium2"/> + <attachFile selector="{{AdminProductImagesSection.imageFileUpload}}" userInput="large.jpg" stepKey="attachLarge2"/> + <waitForPageLoad stepKey="waitForUploadLarge2"/> + <dontSeeElement selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="dontSeeErrorLarge2"/> <!-- Set url key --> <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection2"/> @@ -154,16 +152,16 @@ <actionGroup ref="filterProductGridBySku" stepKey="filterProductGridBySku3"> <argument name="product" value="$$secondProduct$$"/> </actionGroup> - <seeElement selector="img.admin__control-thumbnail[src*='/medium']" stepKey="seeImgInGrid"/> + <seeElement selector="img.admin__control-thumbnail[src*='/large']" stepKey="seeImgInGrid"/> <!-- Go to the category page and see the uploaded image --> <amOnPage url="$$category.name$$.html" stepKey="goToCategoryPage2"/> - <seeElement selector=".products-grid img[src*='/medium']" stepKey="seeUploadedImg"/> + <seeElement selector=".products-grid img[src*='/large']" stepKey="seeUploadedImg"/> <!-- Go to the product page and see the uploaded image --> <amOnPage url="$$secondProduct.name$$.html" stepKey="goToStorefront2"/> <waitForPageLoad stepKey="waitForStorefront2"/> - <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('medium')}}" stepKey="seeMedium2"/> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('Large')}}" stepKey="seeLarge2"/> </test> <test name="AdminSimpleProductRemoveImagesTest"> From 152bbd9a0900257c6cf73381b8bc5a81fa2457d3 Mon Sep 17 00:00:00 2001 From: Yevhen Sentiabov <isentiabov@magento.com> Date: Tue, 9 Oct 2018 15:01:53 +0300 Subject: [PATCH 218/812] MAGETWO-95512: [2.3] Unable to create invoice for an order via Braintree PayPal - Added an exception if Payment Token is not available --- .../Request/PayPal/VaultDataBuilder.php | 2 + .../Request/VaultCaptureDataBuilder.php | 5 + .../Request/VaultCaptureDataBuilderTest.php | 95 +++++++++++++------ app/code/Magento/Braintree/i18n/en_US.csv | 1 + 4 files changed, 72 insertions(+), 31 deletions(-) diff --git a/app/code/Magento/Braintree/Gateway/Request/PayPal/VaultDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/PayPal/VaultDataBuilder.php index a035c84b4cafd..4d63ee4125b74 100644 --- a/app/code/Magento/Braintree/Gateway/Request/PayPal/VaultDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/PayPal/VaultDataBuilder.php @@ -49,6 +49,8 @@ public function build(array $buildSubject) $payment = $paymentDO->getPayment(); $data = $payment->getAdditionalInformation(); + // the payment token could be stored only if a customer checks the Vault flow on storefront + // see https://developers.braintreepayments.com/guides/paypal/vault/javascript/v2#invoking-the-vault-flow if (!empty($data[VaultConfigProvider::IS_ACTIVE_CODE])) { $result[self::$optionsKey] = [ self::$storeInVaultOnSuccess => true diff --git a/app/code/Magento/Braintree/Gateway/Request/VaultCaptureDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/VaultCaptureDataBuilder.php index 4280663178efb..950634ba2d9e2 100644 --- a/app/code/Magento/Braintree/Gateway/Request/VaultCaptureDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/VaultCaptureDataBuilder.php @@ -6,6 +6,8 @@ namespace Magento\Braintree\Gateway\Request; use Magento\Braintree\Gateway\SubjectReader; +use Magento\Framework\Exception\LocalizedException; +use Magento\Payment\Gateway\Command\CommandException; use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Payment\Helper\Formatter; @@ -41,6 +43,9 @@ public function build(array $buildSubject) $payment = $paymentDO->getPayment(); $extensionAttributes = $payment->getExtensionAttributes(); $paymentToken = $extensionAttributes->getVaultPaymentToken(); + if ($paymentToken === null) { + throw new CommandException(__('The Payment Token is not available to perform the request.')); + } return [ 'amount' => $this->formatPrice($this->subjectReader->readAmount($buildSubject)), 'paymentMethodToken' => $paymentToken->getGatewayToken() diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php index 25ccd8b32d10e..d4e1f2745e3f3 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php @@ -3,10 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Braintree\Test\Unit\Gateway\Request; -use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Request\VaultCaptureDataBuilder; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Sales\Api\Data\OrderPaymentExtension; use Magento\Sales\Model\Order\Payment; @@ -26,47 +28,46 @@ class VaultCaptureDataBuilderTest extends \PHPUnit\Framework\TestCase /** * @var PaymentDataObjectInterface|MockObject */ - private $paymentDOMock; + private $paymentDO; /** * @var Payment|MockObject */ - private $paymentMock; + private $payment; /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject + * @var SubjectReader|MockObject */ - private $subjectReaderMock; + private $subjectReader; /** * @inheritdoc */ - protected function setUp() + protected function setUp(): void { - $this->paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->getMockBuilder(Payment::class) + $this->paymentDO = $this->createMock(PaymentDataObjectInterface::class); + $this->payment = $this->getMockBuilder(Payment::class) ->disableOriginalConstructor() ->getMock(); - $this->paymentDOMock->expects(static::once()) - ->method('getPayment') - ->willReturn($this->paymentMock); + $this->paymentDO->method('getPayment') + ->willReturn($this->payment); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + $this->subjectReader = $this->getMockBuilder(SubjectReader::class) ->disableOriginalConstructor() ->getMock(); - $this->builder = new VaultCaptureDataBuilder($this->subjectReaderMock); + $this->builder = new VaultCaptureDataBuilder($this->subjectReader); } /** - * \Magento\Braintree\Gateway\Request\VaultCaptureDataBuilder::build + * Checks the result after builder execution. */ - public function testBuild() + public function testBuild(): void { $amount = 30.00; $token = '5tfm4c'; $buildSubject = [ - 'payment' => $this->paymentDOMock, + 'payment' => $this->paymentDO, 'amount' => $amount, ]; @@ -75,36 +76,68 @@ public function testBuild() 'paymentMethodToken' => $token, ]; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') + $this->subjectReader->method('readPayment') ->with($buildSubject) - ->willReturn($this->paymentDOMock); - $this->subjectReaderMock->expects(self::once()) - ->method('readAmount') + ->willReturn($this->paymentDO); + $this->subjectReader->method('readAmount') ->with($buildSubject) ->willReturn($amount); - $paymentExtensionMock = $this->getMockBuilder(OrderPaymentExtension::class) + /** @var OrderPaymentExtension|MockObject $paymentExtension */ + $paymentExtension = $this->getMockBuilder(OrderPaymentExtension::class) ->setMethods(['getVaultPaymentToken']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $paymentTokenMock = $this->getMockBuilder(PaymentToken::class) + /** @var PaymentToken|MockObject $paymentToken */ + $paymentToken = $this->getMockBuilder(PaymentToken::class) ->disableOriginalConstructor() ->getMock(); - $paymentExtensionMock->expects(static::once()) - ->method('getVaultPaymentToken') - ->willReturn($paymentTokenMock); - $this->paymentMock->expects(static::once()) - ->method('getExtensionAttributes') - ->willReturn($paymentExtensionMock); + $paymentExtension->method('getVaultPaymentToken') + ->willReturn($paymentToken); + $this->payment->method('getExtensionAttributes') + ->willReturn($paymentExtension); - $paymentTokenMock->expects(static::once()) - ->method('getGatewayToken') + $paymentToken->method('getGatewayToken') ->willReturn($token); $result = $this->builder->build($buildSubject); self::assertEquals($expected, $result); } + + /** + * Checks a builder execution if Payment Token doesn't exist. + * + * @expectedException \Magento\Payment\Gateway\Command\CommandException + * @expectedExceptionMessage The Payment Token is not available to perform the request. + */ + public function testBuildWithoutPaymentToken(): void + { + $amount = 30.00; + $buildSubject = [ + 'payment' => $this->paymentDO, + 'amount' => $amount, + ]; + + $this->subjectReader->method('readPayment') + ->with($buildSubject) + ->willReturn($this->paymentDO); + $this->subjectReader->method('readAmount') + ->with($buildSubject) + ->willReturn($amount); + + /** @var OrderPaymentExtension|MockObject $paymentExtension */ + $paymentExtension = $this->getMockBuilder(OrderPaymentExtension::class) + ->setMethods(['getVaultPaymentToken']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->payment->method('getExtensionAttributes') + ->willReturn($paymentExtension); + $paymentExtension->method('getVaultPaymentToken') + ->willReturn(null); + + $this->builder->build($buildSubject); + } } diff --git a/app/code/Magento/Braintree/i18n/en_US.csv b/app/code/Magento/Braintree/i18n/en_US.csv index 6bf677151ed0d..7bd305f546dc6 100644 --- a/app/code/Magento/Braintree/i18n/en_US.csv +++ b/app/code/Magento/Braintree/i18n/en_US.csv @@ -192,3 +192,4 @@ Currency,Currency "Too many concurrent attempts to refund this transaction. Try again later.","Too many concurrent attempts to refund this transaction. Try again later." "Too many concurrent attempts to void this transaction. Try again later.","Too many concurrent attempts to void this transaction. Try again later." "Braintree Settlement","Braintree Settlement" +"The Payment Token is not available to perform the request.","The Payment Token is not available to perform the request." From 3370c8110ef6c479a1886722c447593b0437340a Mon Sep 17 00:00:00 2001 From: Karen_Mkhitaryan <Karen_Mkhitaryan@epam.com> Date: Tue, 9 Oct 2018 17:28:12 +0400 Subject: [PATCH 219/812] MAGETWO-91628: Bundle product price doubled when switching currency - Add minor changes in test --- .../Mftf/Test/CurrencyChangingBundleProductInCartTest.xml | 6 ++++++ .../Test/Mftf/Section/CurrencySetupSection.xml | 1 + 2 files changed, 7 insertions(+) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml index b7e716dc15ece..ded8bb3c83337 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml @@ -28,12 +28,16 @@ <argument name="product" value="BundleProduct"/> </actionGroup> <actionGroup ref="AdminClearFiltersActionGroup" stepKey="ClearFiltersAfter"/> + <waitForPageLoad stepKey="waitForClearFilter"/> <!--Clear Configs--> <amOnPage url="{{AdminLoginPage.url}}" stepKey="navigateToAdmin"/> <waitForPageLoad stepKey="waitForAdminLoginPageLoad"/> <amOnPage url="{{ConfigCurrencySetupPage.url}}" stepKey="navigateToConfigCurrencySetupPage"/> <waitForPageLoad stepKey="waitForConfigCurrencySetupPageForUnselectEuroCurrency"/> <unselectOption selector="{{CurrencySetupSection.allowCurrencies}}" userInput="Euro" stepKey="unselectEuro"/> + <scrollToTopOfPage stepKey="scrollToTopOfPage"/> + <click selector="{{CurrencySetupSection.currencyOptions}}" stepKey="closeOptions"/> + <waitForPageLoad stepKey="waitForCloseOptions"/> <click stepKey="saveUnselectedConfigs" selector="{{AdminConfigSection.saveButton}}"/> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="logout"/> <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> @@ -57,6 +61,8 @@ <actionGroup ref="saveProductForm" stepKey="saveProduct"/> <amOnPage url="{{ConfigCurrencySetupPage.url}}" stepKey="navigateToConfigCurrencySetupPage"/> <waitForPageLoad stepKey="waitForConfigCurrencySetupPage"/> + <conditionalClick selector="{{CurrencySetupSection.currencyOptions}}" dependentSelector="{{CurrencySetupSection.allowCurrencies}}" visible="false" stepKey="openOptions"/> + <waitForPageLoad stepKey="waitForOptions"/> <selectOption selector="{{CurrencySetupSection.allowCurrencies}}" parameterArray="['Euro', 'US Dollar']" stepKey="selectCurrencies"/> <click stepKey="saveConfigs" selector="{{AdminConfigSection.saveButton}}"/> <!-- Go to storefront BundleProduct --> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml index 16101409ad7e8..20fcd1e89360c 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/CurrencySetupSection.xml @@ -10,5 +10,6 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="CurrencySetupSection"> <element name="allowCurrencies" type="select" selector="#currency_options_allow"/> + <element name="currencyOptions" type="select" selector="#currency_options-head"/> </section> </sections> \ No newline at end of file From e250cbf3d3f52ed2590f2ad69b10fd489c416c59 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Mon, 8 Oct 2018 16:51:15 -0500 Subject: [PATCH 220/812] MAGETWO-95140: Placeholder image does not display on Storefront products --- app/code/Magento/Config/Model/Config.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Config/Model/Config.php b/app/code/Magento/Config/Model/Config.php index c6e2412f7e58f..d7cfab8ccf10f 100644 --- a/app/code/Magento/Config/Model/Config.php +++ b/app/code/Magento/Config/Model/Config.php @@ -12,8 +12,8 @@ /** * Backend config model - * Used to save configuration * + * Used to save configuration * @author Magento Core Team <core@magentocommerce.com> * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api @@ -122,6 +122,7 @@ public function __construct( /** * Save config section + * * Require set: section, website, store and groups * * @throws \Exception @@ -237,13 +238,14 @@ private function getField(string $sectionId, string $groupId, string $fieldId): * Get field path * * @param Field $field + * @param string $fieldId * @param array &$oldConfig Need for compatibility with _processGroup() * @param array &$extraOldGroups Need for compatibility with _processGroup() * @return string */ - private function getFieldPath(Field $field, array &$oldConfig, array &$extraOldGroups): string + private function getFieldPath(Field $field, string $fieldId, array &$oldConfig, array &$extraOldGroups): string { - $path = $field->getGroupPath() . '/' . $field->getId(); + $path = $field->getGroupPath() . '/' . $fieldId; /** * Look for custom defined field path @@ -303,7 +305,7 @@ private function getChangedPaths( if (isset($groupData['fields'])) { foreach ($groupData['fields'] as $fieldId => $fieldData) { $field = $this->getField($sectionId, $groupId, $fieldId); - $path = $this->getFieldPath($field, $oldConfig, $extraOldGroups); + $path = $this->getFieldPath($field, $fieldId, $oldConfig, $extraOldGroups); if ($this->isValueChanged($oldConfig, $path, $fieldData)) { $changedPaths[] = $path; } @@ -398,7 +400,7 @@ protected function _processGroup( $backendModel->addData($data); $this->_checkSingleStoreMode($field, $backendModel); - $path = $this->getFieldPath($field, $extraOldGroups, $oldConfig); + $path = $this->getFieldPath($field, $fieldId, $extraOldGroups, $oldConfig); $backendModel->setPath($path)->setValue($fieldData['value']); $inherit = !empty($fieldData['inherit']); @@ -504,6 +506,7 @@ public function setDataByPath($path, $value) /** * Get scope name and scopeId + * * @todo refactor to scope resolver * @return void */ From 2850e6ee21634c9251125cfca82fb83b600e29eb Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 9 Oct 2018 16:40:16 +0300 Subject: [PATCH 221/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Block/DataProviders/ImageUploadConfig.php | 3 + .../Magento/Backend/Block/Media/Uploader.php | 11 +++- .../Product/Helper/Form/Gallery/Content.php | 1 + app/code/Magento/Catalog/Helper/Image.php | 6 ++ .../Magento/Catalog/Model/Product/Image.php | 58 +++++++++++++++++-- .../Model/Product/Image/ParamsBuilder.php | 7 +++ 6 files changed, 81 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php b/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php index 1ba3daf35d2cf..6ec40cfa0b2d4 100644 --- a/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php +++ b/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php @@ -20,6 +20,9 @@ class ImageUploadConfig implements ArgumentInterface */ private $imageUploadConfig; + /** + * @param ImageUploadConfigInterface $imageUploadConfig + */ public function __construct(ImageUploadConfigInterface $imageUploadConfig) { $this->imageUploadConfig = $imageUploadConfig; diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php index c332c91b54b27..941d6f37737fe 100644 --- a/app/code/Magento/Backend/Block/Media/Uploader.php +++ b/app/code/Magento/Backend/Block/Media/Uploader.php @@ -44,6 +44,13 @@ class Uploader extends \Magento\Backend\Block\Widget */ private $imageUploadConfig; + /** + * @var UploadConfigInterface + * @deprecated + * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface + */ + private $imageConfig; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\File\Size $fileSize @@ -58,10 +65,12 @@ public function __construct( array $data = [], Json $jsonEncoder = null, UploadConfigInterface $imageConfig = null, - ImageUploadConfigInterface $imageUploadConfig = null + ImageUploadConfigInterface $imageUploadConfig = null ) { $this->_fileSizeService = $fileSize; $this->jsonEncoder = $jsonEncoder ?: ObjectManager::getInstance()->get(Json::class); + $this->imageConfig = $imageConfig + ?: ObjectManager::getInstance()->get(UploadConfigInterface::class); $this->imageUploadConfig = $imageUploadConfig ?: ObjectManager::getInstance()->get(ImageUploadConfigInterface::class); parent::__construct($context, $data); diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index d9e343fd2b3f0..063503682f4db 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -19,6 +19,7 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\FileSystemException; use Magento\Backend\Block\DataProviders\ImageUploadConfig as ImageUploadConfigDataProvider; + /** * Block for gallery content. */ diff --git a/app/code/Magento/Catalog/Helper/Image.php b/app/code/Magento/Catalog/Helper/Image.php index 74153267f41d6..4a12bf7093943 100644 --- a/app/code/Magento/Catalog/Helper/Image.php +++ b/app/code/Magento/Catalog/Helper/Image.php @@ -407,6 +407,7 @@ public function rotate($angle) /** * Add watermark to image + * * size param in format 100x200 * * @param string $fileName @@ -534,6 +535,8 @@ public function getUrl() } /** + * Save changes + * * @return $this */ public function save() @@ -554,6 +557,8 @@ public function getResizedImageInfo() } /** + * Getter for placeholder url + * * @param null|string $placeholder * @return string */ @@ -656,6 +661,7 @@ protected function getWatermarkPosition() /** * Set watermark size + * * param size in format 100x200 * * @param string $size diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php index 564b817fc167e..8ad4e89d7b480 100644 --- a/app/code/Magento/Catalog/Model/Product/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Image.php @@ -15,6 +15,8 @@ use Magento\Catalog\Model\Product\Image\ParamsBuilder; /** + * Image operations + * * @method string getFile() * @method string getLabel() * @method string getPosition() @@ -209,16 +211,16 @@ class Image extends \Magento\Framework\Model\AbstractModel * @param \Magento\Framework\Image\Factory $imageFactory * @param \Magento\Framework\View\Asset\Repository $assetRepo * @param \Magento\Framework\View\FileSystem $viewFileSystem + * @param ImageFactory $viewAssetImageFactory + * @param PlaceholderFactory $viewAssetPlaceholderFactory * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data - * @param ImageFactory|null $viewAssetImageFactory - * @param PlaceholderFactory|null $viewAssetPlaceholderFactory - * @param SerializerInterface|null $serializer + * @param SerializerInterface $serializer * @param ParamsBuilder $paramsBuilder * @SuppressWarnings(PHPMD.ExcessiveParameterList) - * @SuppressWarnings(PHPMD.UnusedLocalVariable) + * @SuppressWarnings(PHPMD.UnusedLocalVariable)1 */ public function __construct( \Magento\Framework\Model\Context $context, @@ -255,6 +257,8 @@ public function __construct( } /** + * Set image width property + * * @param int $width * @return $this */ @@ -265,6 +269,8 @@ public function setWidth($width) } /** + * Get image width property + * * @return int */ public function getWidth() @@ -273,6 +279,8 @@ public function getWidth() } /** + * Set image height property + * * @param int $height * @return $this */ @@ -283,6 +291,8 @@ public function setHeight($height) } /** + * Get image height property + * * @return int */ public function getHeight() @@ -316,6 +326,8 @@ public function getQuality() } /** + * Set _keepAspectRatio property + * * @param bool $keep * @return $this */ @@ -326,6 +338,8 @@ public function setKeepAspectRatio($keep) } /** + * Set _keepFrame property + * * @param bool $keep * @return $this */ @@ -336,6 +350,8 @@ public function setKeepFrame($keep) } /** + * Set _keepTransparency + * * @param bool $keep * @return $this */ @@ -346,6 +362,8 @@ public function setKeepTransparency($keep) } /** + * Set _constrainOnly + * * @param bool $flag * @return $this */ @@ -356,6 +374,8 @@ public function setConstrainOnly($flag) } /** + * Set background color + * * @param int[] $rgbArray * @return $this */ @@ -366,6 +386,8 @@ public function setBackgroundColor(array $rgbArray) } /** + * Set size + * * @param string $size * @return $this */ @@ -420,6 +442,8 @@ public function setBaseFile($file) } /** + * Get base filename + * * @return string */ public function getBaseFile() @@ -428,6 +452,8 @@ public function getBaseFile() } /** + * Get new file + * * @deprecated 101.1.0 * @return bool|string */ @@ -447,6 +473,8 @@ public function isBaseFilePlaceholder() } /** + * Set image processor + * * @param MagentoImage $processor * @return $this */ @@ -457,6 +485,8 @@ public function setImageProcessor($processor) } /** + * Get image processor + * * @return MagentoImage */ public function getImageProcessor() @@ -475,6 +505,8 @@ public function getImageProcessor() } /** + * Resize image + * * @see \Magento\Framework\Image\Adapter\AbstractAdapter * @return $this */ @@ -488,6 +520,8 @@ public function resize() } /** + * Rotate image + * * @param int $angle * @return $this */ @@ -514,6 +548,7 @@ public function setAngle($angle) /** * Add watermark to image + * * size param in format 100x200 * * @param string $file @@ -573,6 +608,8 @@ public function setWatermark( } /** + * Save file + * * @return $this */ public function saveFile() @@ -587,6 +624,8 @@ public function saveFile() } /** + * Get url + * * @return string */ public function getUrl() @@ -595,6 +634,8 @@ public function getUrl() } /** + * Set destination subdir + * * @param string $dir * @return $this */ @@ -605,6 +646,8 @@ public function setDestinationSubdir($dir) } /** + * Get destination subdir + * * @return string */ public function getDestinationSubdir() @@ -613,6 +656,8 @@ public function getDestinationSubdir() } /** + * Check is image cached + * * @return bool */ public function isCached() @@ -780,7 +825,10 @@ public function getWatermarkHeight() } /** + * Clear cache + * * @return void + * @throws \Magento\Framework\Exception\FileSystemException */ public function clearCache() { @@ -793,6 +841,7 @@ public function clearCache() /** * First check this file on FS + * * If it doesn't exist - try to download it from DB * * @param string $filename @@ -811,6 +860,7 @@ protected function _fileExists($filename) /** * Return resized product image information + * * @return array * @throws NotLoadInfoImageException */ diff --git a/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php b/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php index 21fde84931fa6..f6be7f7392b5e 100644 --- a/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php +++ b/app/code/Magento/Catalog/Model/Product/Image/ParamsBuilder.php @@ -65,6 +65,8 @@ public function __construct( } /** + * Build image params + * * @param array $imageArguments * @return array * @SuppressWarnings(PHPMD.NPathComplexity) @@ -85,6 +87,8 @@ public function build(array $imageArguments): array } /** + * Overwrite default values + * * @param array $imageArguments * @return array */ @@ -110,6 +114,8 @@ private function overwriteDefaultValues(array $imageArguments): array } /** + * Get watermark + * * @param string $type * @return array */ @@ -150,6 +156,7 @@ private function getWatermark(string $type): array /** * Get frame from product_image_white_borders + * * @return bool */ private function hasDefaultFrame(): bool From 38abe3d4558df5ffaa91e3ba5ed7fa73c5172a42 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 9 Oct 2018 16:50:25 +0300 Subject: [PATCH 222/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- app/code/Magento/Catalog/Helper/Image.php | 4 ++-- app/code/Magento/Catalog/Model/Product/Image.php | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Helper/Image.php b/app/code/Magento/Catalog/Helper/Image.php index 4a12bf7093943..170f1209ad9e6 100644 --- a/app/code/Magento/Catalog/Helper/Image.php +++ b/app/code/Magento/Catalog/Helper/Image.php @@ -408,7 +408,7 @@ public function rotate($angle) /** * Add watermark to image * - * size param in format 100x200 + * Size param in format 100x200 * * @param string $fileName * @param string $position @@ -662,7 +662,7 @@ protected function getWatermarkPosition() /** * Set watermark size * - * param size in format 100x200 + * Param size in format 100x200 * * @param string $size * @return $this diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php index 8ad4e89d7b480..adde1263e1bf9 100644 --- a/app/code/Magento/Catalog/Model/Product/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Image.php @@ -549,7 +549,7 @@ public function setAngle($angle) /** * Add watermark to image * - * size param in format 100x200 + * Size param in format 100x200 * * @param string $file * @param string $position @@ -690,7 +690,8 @@ public function getWatermarkFile() /** * Get relative watermark file path - * or false if file not found + * + * Return false if file not found * * @return string | bool */ From dd560f3c985e890fd21cb97b3fd6b5f5b190a312 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Tue, 9 Oct 2018 16:32:45 +0300 Subject: [PATCH 223/812] MAGETWO-91640: Scheduled Import of Products fails on error when errors should be skipped - Integration test fix --- .../integration/testsuite/Magento/Catalog/_files/categories.php | 2 +- .../Magento/CatalogImportExport/Model/Import/ProductTest.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php index a903274793c34..9a1a6f24dffc8 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php @@ -84,7 +84,7 @@ $category = $objectManager->create(\Magento\Catalog\Model\Category::class); $category->isObjectNew(true); $category->setId(6) - ->setName('Category 2') + ->setName('Category 2.1') ->setParentId(2) ->setPath('1/2/6') ->setLevel(2) diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 237d7660da9bd..296c36caed5a0 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -958,6 +958,7 @@ public function testInvalidSkuLink() $errors = $this->_model->setParameters( [ 'behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, + Import::FIELD_NAME_VALIDATION_STRATEGY => null, 'entity' => 'catalog_product' ] )->setSource( From 6e03f0ff8d21259526d6948de51ed29266241d61 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 9 Oct 2018 17:00:58 +0300 Subject: [PATCH 224/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../view/adminhtml/templates/browser/content/uploader.phtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml index c6810f774238c..54f42bb4ecc1f 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml @@ -19,9 +19,9 @@ foreach ($filters as $media_type) { $resizeConfig = ($block->getImageUploadConfigData()->getIsResizeEnabled()) ? "{action: 'resize', maxWidth: " - . $block->escapeHtml($block->getImageUploadMaxWidth()) + . $block->getImageUploadMaxWidth() . ", maxHeight: " - . $block->escapeHtml($block->getImageUploadMaxHeight()) + . $block->getImageUploadMaxHeight() . "}" : "{action: 'resize'}"; ?> @@ -153,7 +153,7 @@ require([ fileTypes: /^image\/(gif|jpeg|png)$/, maxFileSize: <?= (int) $block->getFileSizeService()->getMaxFileSize() ?> * 10 }, - <?= /* @noEscape*/ $resizeConfig ?>, + <?= $block->escapeHtml($resizeConfig) ?>, { action: 'save' }] From 65670eacceaa1d812ff251c2304540859e9b4142 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 9 Oct 2018 18:18:57 +0300 Subject: [PATCH 225/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Magento/Backend/view/adminhtml/web/js/media-uploader.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js index 2a15f5262bda1..6789dfa3f2b8e 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js +++ b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js @@ -44,7 +44,9 @@ define([ }; if (isResizeEnabled === 0) { - resizeConfiguration = {action: 'resize'}; + resizeConfiguration = { + action: 'resize' + }; } this.element.find('input[type=file]').fileupload({ From 4811ede46c2446361c5bdcb9aeb879ed66ffebf0 Mon Sep 17 00:00:00 2001 From: pganapat <prabhuramgr28493@gmail.com> Date: Fri, 5 Oct 2018 14:08:30 -0500 Subject: [PATCH 226/812] MAGETWO-95436: Unable to place orders with custom customer address attributes - Modified address-converter to suite QuoteShipmentEstimation endpoint payload. Fixed lint issues --- .../view/frontend/web/js/model/address-converter.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js b/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js index a1aacf6e80320..9b20a782c38d9 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js @@ -58,6 +58,16 @@ define([ } delete addressData['region_id']; + if (addressData['custom_attributes']) { + addressData['custom_attributes'] = Object.entries(addressData['custom_attributes']) + .map(function (customAttribute) { + return { + 'attribute_code': customAttribute[0], + 'value': customAttribute[1] + }; + }); + } + return address(addressData); }, From 70b9091543b958f599249231e9f72a603c60c233 Mon Sep 17 00:00:00 2001 From: avattam <> Date: Tue, 9 Oct 2018 12:04:56 -0500 Subject: [PATCH 227/812] MAGETWO-95111: Creating new storeview code uniqueness validation - added code change for validating the code uniqueness --- app/code/Magento/Backend/view/adminhtml/web/js/validate-store.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/validate-store.js b/app/code/Magento/Backend/view/adminhtml/web/js/validate-store.js index 0a692a9b868cc..c2a0d4dab1fb3 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/js/validate-store.js +++ b/app/code/Magento/Backend/view/adminhtml/web/js/validate-store.js @@ -67,6 +67,7 @@ define([ * 'Confirm' action handler. */ confirm: function () { + $('body').trigger('processStart'); dataPost().postData(requestData); } } From 1550eb5e27f7e520612dcb4fe1d2c86de8ce42d6 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 9 Oct 2018 12:06:43 -0500 Subject: [PATCH 228/812] MAGETWO-94962: Unable to set default option for swatch attribute --- .../Catalog/view/adminhtml/web/js/options.js | 11 +++- .../adminhtml/web/js/product-attributes.js | 11 +++- .../Handler/CatalogProductAttribute/Curl.php | 62 +++++-------------- .../Handler/SwatchProductAttribute/Curl.php | 31 ++++++---- .../Adminhtml/Product/AttributeTest.php | 14 +++-- .../Adminhtml/Product/AttributeTest.php | 36 ++++++----- .../Serialize/Serializer/FormData.php | 25 +++++++- 7 files changed, 103 insertions(+), 87 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js index 5a8dc1df86074..7adc0dcfdf408 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/options.js @@ -182,15 +182,22 @@ define([ }); } editForm.on('beforeSubmit', function () { - var optionContainer = optionPanel.find('table tbody'); + var optionContainer = optionPanel.find('table tbody'), + optionsValues; if (optionPanel.hasClass(activePanelClass)) { + optionsValues = jQuery.map( + optionContainer.find('tr'), + function (row) { + return jQuery(row).find('input, select, textarea').serialize(); + } + ); jQuery('<input>') .attr({ type: 'hidden', name: 'serialized_options' }) - .val(optionContainer.find('input, select, textarea').serialize()) + .val(JSON.stringify(optionsValues)) .prependTo(editForm); } tableBody = optionContainer.detach(); diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js index 2f8fcbdd7d40d..8b513bc8532db 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js @@ -438,19 +438,24 @@ define([ .collapse('hide'); editForm.on('beforeSubmit', function () { - var optionContainer; + var optionContainer, optionsValues; activePanel = swatchTextPanel.hasClass(activePanelClass) ? swatchTextPanel : swatchVisualPanel; optionContainer = activePanel.find('table tbody'); if (activePanel.hasClass(activePanelClass)) { + optionsValues = $.map( + optionContainer.find('tr'), + function (row) { + return $(row).find('input, select, textarea').serialize(); + } + ); $('<input>') .attr({ type: 'hidden', name: 'serialized_options' }) - .val(optionContainer - .find('input, select, textarea').serialize()) + .val(JSON.stringify(optionsValues)) .prependTo(editForm); } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php index 57d775cdeb736..7ecaeb5ea7b82 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php @@ -91,15 +91,18 @@ public function persist(FixtureInterface $fixture = null) $data['frontend_label'] = [0 => $data['frontend_label']]; if (isset($data['options'])) { + $optionsData = []; foreach ($data['options'] as $key => $values) { + $optionRowData = []; $index = 'option_' . $key; if ($values['is_default'] == 'Yes') { - $data['default'][] = $index; + $optionRowData['default'][] = $index; } - $data['option']['value'][$index] = [$values['admin'], $values['view']]; - $data['option']['order'][$index] = $key; + $optionRowData['option']['value'][$index] = [$values['admin'], $values['view']]; + $optionRowData['option']['order'][$index] = $key; + $optionsData[] = $optionRowData; } - unset($data['options']); + $data['options'] = $optionsData; } $data = $this->changeStructureOfTheData($data); @@ -139,12 +142,12 @@ public function persist(FixtureInterface $fixture = null) * @param array $data * @return array */ - protected function changeStructureOfTheData(array $data) + protected function changeStructureOfTheData(array $data): array { - $serializedOptions = $this->getSerializeOptions($data, ['option']); + $serializedOptions = $this->getSerializeOptions($data['options']); if ($serializedOptions) { $data['serialized_options'] = $serializedOptions; - unset($data['option']); + unset($data['options']); } return $data; @@ -154,52 +157,15 @@ protected function changeStructureOfTheData(array $data) * Provides serialized product attribute options. * * @param array $data - * @param array $optionKeys - * @return array + * @return string */ - protected function getSerializeOptions(array $data, array $optionKeys): string + protected function getSerializeOptions(array $data): string { $options = []; - foreach ($optionKeys as $optionKey) { - if (!empty($data[$optionKey])) { - $options = array_merge( - $options, - $this->getEncodedOptions([$optionKey => $data[$optionKey]]) - ); - } + foreach ($data as $optionRowData) { + $options[] = http_build_query($optionRowData); } return json_encode($options); } - - /** - * Provides encoded attribute values. - * - * @param array $data - * @return array - */ - private function getEncodedOptions(array $data): array - { - $optionsData = []; - $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($data)); - foreach ($iterator as $value) { - $depth = $iterator->getDepth(); - $option = ''; - - $level = 0; - $option .= $iterator->getSubIterator($level)->key(); - $level++; - - while ($level <= $depth) { - $option .= '[' . $iterator->getSubIterator($level)->key() . ']'; - $level++; - } - - $option .= '=' . $value; - - $optionsData[] = $option; - } - - return $optionsData; - } } diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php index 5e4a5cc45fe69..f4adb9dec1250 100644 --- a/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php @@ -29,23 +29,32 @@ public function __construct(DataInterface $configuration, EventManagerInterface ]; } + /** + * @inheritdoc + */ + protected function changeStructureOfTheData(array $data): array + { + return parent::changeStructureOfTheData($data); + } + /** * Re-map options from default options structure to swatches structure, * as swatches was initially created with name convention differ from other attributes. * - * @param array $data - * @return array + * @inheritdoc */ - protected function changeStructureOfTheData(array $data) + protected function getSerializeOptions(array $data): string { - $data['optiontext'] = $data['option']; - $data['swatchtext'] = [ - 'value' => $data['option']['value'] - ]; - $data['serialized_options'] = $this->getSerializeOptions($data, ['optiontext', 'swatchtext']); - unset($data['option']); - $data = parent::changeStructureOfTheData($data); + $options = []; + foreach ($data as $optionRowData) { + $optionRowData['optiontext'] = $optionRowData['option']; + $optionRowData['swatchtext'] = [ + 'value' => $optionRowData['option']['value'] + ]; + unset($optionRowData['option']); + $options[] = http_build_query($optionRowData); + } - return $data; + return json_encode($options); } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php index 1f70ad0f7df6b..101e9f596be52 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php @@ -298,13 +298,15 @@ public function testLargeOptionsDataSet() $optionsData = []; $expectedOptionsLabels = []; for ($i = 0; $i < $optionsCount; $i++) { - $order = $i + 1; - $expectedOptionLabelOnStoreView = "value_{$i}_store_1"; + $expectedOptionLabelOnStoreView = 'value_' . $i . '_store_1'; $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; - $optionsData []= "option[order][option_{$i}]={$order}"; - $optionsData []= "option[value][option_{$i}][0]=value_{$i}_admin"; - $optionsData []= "option[value][option_{$i}][1]={$expectedOptionLabelOnStoreView}"; - $optionsData []= "option[delete][option_{$i}="; + $optionId = 'option_' . $i; + $optionRowData = []; + $optionRowData["option"]["order"][$optionId] = $i + 1; + $optionRowData["option"]["value"][$optionId][0] = 'value_' . $i . '_admin'; + $optionRowData["option"]["value"][$optionId][1] = $expectedOptionLabelOnStoreView; + $optionRowData["option"]["delete"][$optionId] = ''; + $optionsData[] = http_build_query($optionRowData); } $attributeData['serialized_options'] = json_encode($optionsData); $this->getRequest()->setMethod(HttpRequest::METHOD_POST); diff --git a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php index 5b7a80bb38dfd..10f6703f583d7 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php @@ -55,15 +55,17 @@ private function getSwatchVisualDataSet(int $optionsCount) : array $optionsData = []; $expectedOptionsLabels = []; for ($i = 0; $i < $optionsCount; $i++) { - $order = $i + 1; - $expectedOptionLabelOnStoreView = "value_{$i}_store_1"; + $expectedOptionLabelOnStoreView = 'value_' . $i .'_store_1'; $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; - $optionsData []= "optionvisual[order][option_{$i}]={$order}"; - $optionsData []= "defaultvisual[]=option_{$i}"; - $optionsData []= "swatchvisual[value][option_{$i}]={$this->getRandomColor()}"; - $optionsData []= "optionvisual[value][option_{$i}][0]=value_{$i}_admin"; - $optionsData []= "optionvisual[value][option_{$i}][1]={$expectedOptionLabelOnStoreView}"; - $optionsData []= "optionvisual[delete][option_{$i}]="; + $optionId = 'option_' .$i; + $optionRowData = []; + $optionRowData["optionvisual"]["order"][$optionId] = $i + 1; + $optionRowData["defaultvisual"][] = $optionId; + $optionRowData["swatchvisual"]["value"][$optionId] = $this->getRandomColor(); + $optionRowData["optionvisual"]["value"][$optionId][0] = 'value_' . $i .'_admin'; + $optionRowData["optionvisual"]["value"][$optionId][1] = $expectedOptionLabelOnStoreView; + $optionRowData["optionvisual"]["delete"][$optionId] = ''; + $optionsData[] = http_build_query($optionRowData); } return [ 'attribute_data' => array_merge_recursive( @@ -95,15 +97,17 @@ private function getSwatchTextDataSet(int $optionsCount) : array $optionsData = []; $expectedOptionsLabels = []; for ($i = 0; $i < $optionsCount; $i++) { - $order = $i + 1; - $expectedOptionLabelOnStoreView = "value_{$i}_store_1"; + $expectedOptionLabelOnStoreView = 'value_' . $i . '_store_1'; $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; - $optionsData []= "optiontext[order][option_{$i}]={$order}"; - $optionsData []= "defaulttext[]=option_{$i}"; - $optionsData []= "swatchtext[value][option_{$i}]=x{$i}"; - $optionsData []= "optiontext[value][option_{$i}][0]=value_{$i}_admin"; - $optionsData []= "optiontext[value][option_{$i}][1]={$expectedOptionLabelOnStoreView}"; - $optionsData []= "optiontext[delete][option_{$i}]="; + $optionId = 'option_' . $i; + $optionRowData = []; + $optionRowData["optiontext"]["order"][$optionId] = $i + 1; + $optionRowData["defaulttext"][] = $optionId; + $optionRowData["swatchtext"]["value"][$optionId] = 'x' . $i ; + $optionRowData["optiontext"]["value"][$optionId][0] = 'value_' . $i . '_admin'; + $optionRowData["optiontext"]["value"][$optionId][1]= $expectedOptionLabelOnStoreView; + $optionRowData["optiontext"]["delete"][$optionId]=''; + $optionsData[] = http_build_query($optionRowData); } return [ 'attribute_data' => array_merge_recursive( diff --git a/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php b/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php index b2597afdf92a5..a945822d92f97 100644 --- a/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php +++ b/lib/internal/Magento/Framework/Serialize/Serializer/FormData.php @@ -13,6 +13,19 @@ */ class FormData { + /** + * @var Json + */ + private $serializer; + + /** + * @param Json $serializer + */ + public function __construct(Json $serializer) + { + $this->serializer = $serializer; + } + /** * Provides form data from the serialized data. * @@ -22,8 +35,18 @@ class FormData */ public function unserialize(string $serializedData): array { + $encodedFields = $this->serializer->unserialize($serializedData); + + if (!is_array($encodedFields)) { + throw new \InvalidArgumentException('Unable to unserialize value.'); + } + $formData = []; - parse_str($serializedData, $formData); + foreach ($encodedFields as $item) { + $decodedFieldData = []; + parse_str($item, $decodedFieldData); + $formData = array_replace_recursive($formData, $decodedFieldData); + } return $formData; } From f3b5613b878aa682aa3426374585bdf1b1cb58e1 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Tue, 9 Oct 2018 14:20:32 -0500 Subject: [PATCH 229/812] MAGETWO-95140: Placeholder image does not display on Storefront products - Add functional test --- .../Catalog/Test/Mftf/Data/ImageData.xml | 28 ++++ ...inProductImagePlaceholderConfigSection.xml | 37 +++++ ...inConfigureProductImagePlaceholderTest.xml | 145 ++++++++++++++++++ .../StorefrontMiniCartActionGroup.xml | 14 ++ .../Section/StorefrontMiniCartSection.xml | 1 + 5 files changed, 225 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/ImageData.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/AdminProductImagePlaceholderConfigSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/AdminConfigureProductImagePlaceholderTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ImageData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ImageData.xml new file mode 100644 index 0000000000000..a2391dda54809 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ImageData.xml @@ -0,0 +1,28 @@ +<?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="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="placeholderBaseImage" type="imageFile"> + <data key="file">adobe-base.jpg</data> + <data key="name">adobe-base</data> + <data key="extension">jpg</data> + </entity> + + <entity name="placeholderSmallImage" type="imageFile"> + <data key="file">adobe-small.jpg</data> + <data key="name">adobe-small</data> + <data key="extension">jpg</data> + </entity> + + <entity name="placeholderThumbnailImage" type="imageFile"> + <data key="file">adobe-thumb.jpg</data> + <data key="name">adobe-thumb</data> + <data key="extension">jpg</data> + </entity> +</entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductImagePlaceholderConfigSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductImagePlaceholderConfigSection.xml new file mode 100644 index 0000000000000..7558b13d624bb --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductImagePlaceholderConfigSection.xml @@ -0,0 +1,37 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminProductImagePlaceholderConfigSection"> + <element name="sectionHeader" type="text" selector="#catalog_placeholder-head"/> + <!--Base image placeholder--> + <element name="baseImageInput" type="file" selector="#catalog_placeholder_image_placeholder" timeout="10"/> + <element name="baseImageDelete" type="checkbox" selector="#catalog_placeholder_image_placeholder_delete"/> + <element name="baseImage" type="text" selector="#catalog_placeholder_image_placeholder_image"/> + <element name="baseImageBySrc" type="text" selector="#catalog_placeholder_image_placeholder_image[src*='{{var}}']" parameterized="true"/> + + <!--Small image placeholder--> + <element name="smallImageInput" type="file" selector="#catalog_placeholder_small_image_placeholder" timeout="10"/> + <element name="smallImageDelete" type="checkbox" selector="#catalog_placeholder_small_image_placeholder_delete"/> + <element name="smallImage" type="text" selector="#catalog_placeholder_small_image_placeholder_image"/> + <element name="smallImageBySrc" type="text" selector="#catalog_placeholder_small_image_placeholder_image[src*='{{var}}']" parameterized="true"/> + + <!--Swatch image placeholder--> + <element name="swatchImageInput" type="file" selector="#catalog_placeholder_swatch_image_placeholder" timeout="10"/> + <element name="swatchImageDelete" type="checkbox" selector="#catalog_placeholder_swatch_image_placeholder_delete"/> + <element name="swatchImage" type="text" selector="#catalog_placeholder_swatch_image_placeholder_image"/> + <element name="swatchImageBySrc" type="text" selector="#catalog_placeholder_swatch_image_placeholder_image[src*='{{var}}']" parameterized="true"/> + + <!--Thumbnail image placeholder--> + <element name="thumbnailImageInput" type="file" selector="#catalog_placeholder_thumbnail_placeholder" timeout="10"/> + <element name="thumbnailImageDelete" type="checkbox" selector="#catalog_placeholder_thumbnail_placeholder_delete"/> + <element name="thumbnailImage" type="text" selector="#catalog_placeholder_thumbnail_placeholder_image"/> + <element name="thumbnailImageBySrc" type="text" selector="#catalog_placeholder_thumbnail_placeholder_image[src*='{{var}}']" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminConfigureProductImagePlaceholderTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminConfigureProductImagePlaceholderTest.xml new file mode 100644 index 0000000000000..4d97dee56f059 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminConfigureProductImagePlaceholderTest.xml @@ -0,0 +1,145 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminConfigureProductImagePlaceholderTest"> + + <annotations> + <features value="Configuration"/> + <stories value="Configure product placeholder images"/> + <title value="Admin is able to configure product placeholder images"/> + <description value="Admin should be able to configure the images used for product image placeholders. The configured placeholders should be seen on the frontend when an image has no image."/> + <severity value="MAJOR"/> + <testCaseId value="MC-5005"/> + <group value="configuration"/> + </annotations> + + <before> + <createData entity="ApiCategory" stepKey="category"/> + <!--Create product with no images--> + <createData entity="ApiSimpleProduct" stepKey="productNoImages"> + <requiredEntity createDataKey="category"/> + </createData> + <!--Create product with small, base, and thumbnail image--> + <createData entity="ApiSimpleProduct" stepKey="productWithImages"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiProductAttributeMediaGalleryEntryTestImage" stepKey="productImage"> + <requiredEntity createDataKey="productWithImages"/> + </createData> + </before> + + <after> + <!--Unset product image placeholders--> + <amOnPage url="{{CatalogConfigPage.url}}" stepKey="goToCatalogConfigurationPageAfter"/> + <waitForPageLoad stepKey="waitForConfigurationPageLoadAfter"/> + <conditionalClick selector="{{AdminProductImagePlaceholderConfigSection.sectionHeader}}" dependentSelector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" visible="false" stepKey="openPlaceholderSectionAfter"/> + <waitForElementVisible selector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" stepKey="waitForPlaceholderSectionOpenAfter"/> + <!--Delete base placeholder--> + <checkOption selector="{{AdminProductImagePlaceholderConfigSection.baseImageDelete}}" stepKey="checkDeleteBasePlaceholder"/> + <!--Delete small placeholder--> + <checkOption selector="{{AdminProductImagePlaceholderConfigSection.smallImageDelete}}" stepKey="checkDeleteSmallPlaceholder"/> + <!--Delete thumbnail placeholder--> + <checkOption selector="{{AdminProductImagePlaceholderConfigSection.thumbnailImageDelete}}" stepKey="checkDeleteThumbnailPlaceholder"/> + <!--Save config to delete placeholders--> + <click selector="{{AdminMainActionsSection.save}}" stepKey="saveConfigWithPlaceholders"/> + <!--See placeholders are empty--> + <conditionalClick selector="{{AdminProductImagePlaceholderConfigSection.sectionHeader}}" dependentSelector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" visible="false" stepKey="openPlaceholderSection2"/> + <waitForElementVisible selector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" stepKey="waitForPlaceholderSectionOpen2"/> + <dontSeeElement selector="{{AdminProductImagePlaceholderConfigSection.baseImage}}" stepKey="dontSeeBaseImageSet"/> + <dontSeeElement selector="{{AdminProductImagePlaceholderConfigSection.smallImage}}" stepKey="dontSeeSmallImageSet"/> + <dontSeeElement selector="{{AdminProductImagePlaceholderConfigSection.thumbnailImage}}" stepKey="dontSeeThumbnailImageSet"/> + <dontSeeElement selector="{{AdminProductImagePlaceholderConfigSection.swatchImage}}" stepKey="dontSeeSwatchImageSet"/> + + <!--Delete prerequisite entities--> + <deleteData createDataKey="category" stepKey="deleteCategory"/> + <deleteData createDataKey="productNoImages" stepKey="deleteProductNoImages"/> + <deleteData createDataKey="productWithImages" stepKey="deleteProductWithImages"/> + </after> + + <actionGroup ref="LoginAsAdmin" stepKey="loginToAdminArea"/> + + <!--Admin area: configure Product Image Placeholders--> + <comment userInput="Configure product image placeholders in store config" stepKey="configurePlaceholderComment"/> + <amOnPage url="{{CatalogConfigPage.url}}" stepKey="goToCatalogConfigurationPage"/> + <waitForPageLoad stepKey="waitForConfigurationPageLoad1"/> + <conditionalClick selector="{{AdminProductImagePlaceholderConfigSection.sectionHeader}}" dependentSelector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" visible="false" stepKey="openPlaceholderSection1"/> + <waitForElementVisible selector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" stepKey="waitForPlaceholderSectionOpen1"/> + <!--Set base placeholder--> + <attachFile selector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" userInput="{{placeholderBaseImage.file}}" stepKey="uploadBasePlaceholder"/> + <!--Set small placeholder--> + <attachFile selector="{{AdminProductImagePlaceholderConfigSection.smallImageInput}}" userInput="{{placeholderSmallImage.file}}" stepKey="uploadSmallPlaceholder"/> + <!--Set thumbnail placeholder--> + <attachFile selector="{{AdminProductImagePlaceholderConfigSection.thumbnailImageInput}}" userInput="{{placeholderThumbnailImage.file}}" stepKey="uploadThumbnailPlaceholder"/> + <!--Save config with placeholders--> + <click selector="{{AdminMainActionsSection.save}}" stepKey="saveConfigWithPlaceholders"/> + <!--See images are saved--> + <conditionalClick selector="{{AdminProductImagePlaceholderConfigSection.sectionHeader}}" dependentSelector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" visible="false" stepKey="openPlaceholderSection2"/> + <waitForElementVisible selector="{{AdminProductImagePlaceholderConfigSection.baseImageInput}}" stepKey="waitForPlaceholderSectionOpen2"/> + <seeElement selector="{{AdminProductImagePlaceholderConfigSection.baseImageBySrc(placeholderBaseImage.name)}}" stepKey="seeBasePlaceholderSet"/> + <seeElement selector="{{AdminProductImagePlaceholderConfigSection.smallImageBySrc(placeholderSmallImage.name)}}" stepKey="seeSmallPlaceholderSet"/> + <seeElement selector="{{AdminProductImagePlaceholderConfigSection.thumbnailImageBySrc(placeholderThumbnailImage.name)}}" stepKey="seeThumbnailPlaceholderSet"/> + <dontSeeElement selector="{{AdminProductImagePlaceholderConfigSection.swatchImage}}" stepKey="dontSeeSwatchImageSet"/> + + <!--See correct placeholder images on category page--> + <comment userInput="Check placeholder images on the storefront" stepKey="checkStorefrontComment"/> + <amOnPage url="$$category.name$$.html" stepKey="goToCategoryStorefront1"/> + <waitForPageLoad stepKey="waitForStorefrontCategory1"/> + <!--Product with no images uses placeholder--> + <seeElement selector="{{StorefrontCategoryProductSection.ProductImageByName($$productNoImages.name$$)}}" stepKey="seeProductNoImagesInCategory"/> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$productNoImages.name$$)}}" userInput="src" stepKey="getSmallPlaceholderImageSrc"/> + <assertContains stepKey="checkSmallPlaceholderImage"> + <actualResult type="variable">$getSmallPlaceholderImageSrc</actualResult> + <expectedResult type="string">{{placeholderSmallImage.name}}</expectedResult> + </assertContains> + <!--Product with images does not use placeholder--> + <seeElement selector="{{StorefrontCategoryProductSection.ProductTitleByName($$productWithImages.name$$)}}" stepKey="seeProductWithImagesInCategory"/> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$productWithImages.name$$)}}" userInput="src" stepKey="getSmallNonPlaceholderImageSrc"/> + <assertNotContains stepKey="checkSmallPlaceholderImageNotUsed"> + <actualResult type="variable">$getSmallNonPlaceholderImageSrc</actualResult> + <expectedResult type="string">{{placeholderSmallImage.name}}</expectedResult> + </assertNotContains> + + <!--Check base image on product page--> + <!--Product which is using placeholder--> + <click selector="{{StorefrontCategoryProductSection.ProductImageByName($$productNoImages.name$$)}}" stepKey="goToProductNoImages"/> + <waitForPageLoad stepKey="waitForProductPageLoad1"/> + <seeInCurrentUrl url="$$productNoImages.sku$$" stepKey="seeCorrectProductPage1"/> + <seeElement selector="{{StorefrontProductMediaSection.imageFile(placeholderBaseImage.name)}}" stepKey="seeBasePlaceholderImage"/> + <click selector="{{StorefrontProductPageSection.addToCartBtn}}" stepKey="addProductToCart1"/> + <waitForElementVisible selector="{{StorefrontProductPageSection.successMsg}}" stepKey="waitForProductAdded1"/> + <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="openMiniCart1"/> + <grabAttributeFrom selector="{{StorefrontMinicartSection.productImageByName($$productNoImages.name$$)}}" userInput="src" stepKey="getThumbnailPlaceholderImageSrc"/> + <assertContains stepKey="checkThumbnailPlaceholderImage"> + <actualResult type="variable">$getThumbnailPlaceholderImageSrc</actualResult> + <expectedResult type="string">{{placeholderThumbnailImage.name}}</expectedResult> + </assertContains> + <actionGroup ref="removeProductFromMiniCart" stepKey="removeProductFromCart1"> + <argument name="productName" value="$$productNoImages.name$$"/> + </actionGroup> + <!--Product which is NOT using placeholder--> + <amOnPage url="$$category.name$$.html" stepKey="goToCategoryStorefront2"/> + <waitForPageLoad stepKey="waitForStorefrontCategory2"/> + <click selector="{{StorefrontCategoryProductSection.ProductImageByName($$productWithImages.name$$)}}" stepKey="goToProductWithImages"/> + <waitForPageLoad stepKey="waitForProductPageLoad2"/> + <seeInCurrentUrl url="$$productWithImages.sku$$" stepKey="seeCorrectProductPage2"/> + <dontSeeElement selector="{{StorefrontProductMediaSection.imageFile(placeholderBaseImage.name)}}" stepKey="dontSeeBasePlaceholderImage"/> + <click selector="{{StorefrontProductPageSection.addToCartBtn}}" stepKey="addProductToCart2"/> + <waitForElementVisible selector="{{StorefrontProductPageSection.successMsg}}" stepKey="waitForProductAdded2"/> + <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="openMiniCart2"/> + <grabAttributeFrom selector="{{StorefrontMinicartSection.productImageByName($$productWithImages.name$$)}}" userInput="src" stepKey="getThumbnailImageSrc"/> + <assertNotContains stepKey="checkThumbnailImage"> + <actualResult type="variable">$getThumbnailImageSrc</actualResult> + <expectedResult type="string">{{placeholderThumbnailImage.name}}</expectedResult> + </assertNotContains> + <actionGroup ref="removeProductFromMiniCart" stepKey="removeProductFromCart2"> + <argument name="productName" value="$$productWithImages.name$$"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontMiniCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontMiniCartActionGroup.xml index cb53a2a4f381f..7a5c5e1d15872 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontMiniCartActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontMiniCartActionGroup.xml @@ -21,4 +21,18 @@ <waitForElementVisible selector="{{StorefrontMinicartSection.viewAndEditCart}}" stepKey="waitForViewAndEditCartVisible"/> <see selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{productName}}" stepKey="seeInMiniCart"/> </actionGroup> + + <!--Remove an item from the cart using minicart--> + <actionGroup name="removeProductFromMiniCart"> + <arguments> + <argument name="productName" type="string"/> + </arguments> + <conditionalClick selector="{{StorefrontMinicartSection.showCart}}" dependentSelector="{{StorefrontMinicartSection.miniCartOpened}}" visible="false" stepKey="openMiniCart"/> + <waitForElementVisible selector="{{StorefrontMinicartSection.viewAndEditCart}}" stepKey="waitForMiniCartOpen"/> + <click selector="{{StorefrontMinicartSection.deleteMiniCartItemByName(productName)}}" stepKey="clickDelete"/> + <waitForElementVisible selector="{{StoreFrontRemoveItemModalSection.message}}" stepKey="waitForConfirmationModal"/> + <see selector="{{StoreFrontRemoveItemModalSection.message}}" userInput="Are you sure you would like to remove this item from the shopping cart?" stepKey="seeDeleteConfirmationMessage"/> + <click selector="{{StoreFrontRemoveItemModalSection.ok}}" stepKey="confirmDelete"/> + <waitForPageLoad stepKey="waitForDeleteToFinish"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml index c8ff851ae54ab..231713075881e 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml @@ -22,6 +22,7 @@ <element name="viewAndEditCart" type="button" selector=".action.viewcart" timeout="30"/> <element name="miniCartItemsText" type="text" selector=".minicart-items"/> <element name="deleteMiniCartItem" type="button" selector=".action.delete" timeout="30"/> + <element name="deleteMiniCartItemByName" type="button" selector="//ol[@id='mini-cart']//div[contains(., '{{var}}')]//a[contains(@class, 'delete')]" parameterized="true"/> <element name="miniCartSubtotalField" type="text" selector=".block-minicart .amount span.price"/> <element name="itemQuantity" type="input" selector="//a[text()='{{productName}}']/../..//input[contains(@class,'cart-item-qty')]" parameterized="true"/> <element name="itemQuantityUpdate" type="button" selector="//a[text()='{{productName}}']/../..//span[text()='Update']" parameterized="true"/> From ac2128993d3b0316ba6dc267d553a1d13001222b Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 9 Oct 2018 15:27:14 -0500 Subject: [PATCH 230/812] MAGETWO-95238: Cannot reset customer password from Admin Panel --- .../Block/Adminhtml/Edit/ResetPasswordButton.php | 5 +---- .../Controller/Adminhtml/Index/ResetPassword.php | 4 ++-- .../view/adminhtml/web/edit/post-wrapper.js | 8 -------- .../Adminhtml/Index/ResetPasswordTest.php | 14 +++++++------- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php index c38f182f275f2..aa93785116851 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/ResetPasswordButton.php @@ -25,10 +25,7 @@ public function getButtonData() $data = [ 'label' => __('Reset Password'), 'class' => 'reset reset-password', - 'data_attribute' => [ - 'url' => $this->getResetPasswordUrl() - ], - 'on_click' => '', + 'on_click' => sprintf("location.href = '%s';", $this->getResetPasswordUrl()), 'sort_order' => 60, ]; } diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php index 6ef6ddd0e732b..69af6f4fb1b27 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php @@ -5,11 +5,11 @@ */ namespace Magento\Customer\Controller\Adminhtml\Index; -use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\SecurityViolationException; -class ResetPassword extends \Magento\Customer\Controller\Adminhtml\Index implements HttpPostActionInterface +class ResetPassword extends \Magento\Customer\Controller\Adminhtml\Index implements HttpGetActionInterface { /** * Reset password handler diff --git a/app/code/Magento/Customer/view/adminhtml/web/edit/post-wrapper.js b/app/code/Magento/Customer/view/adminhtml/web/edit/post-wrapper.js index 27fa5eb783bba..76b060015c5ff 100644 --- a/app/code/Magento/Customer/view/adminhtml/web/edit/post-wrapper.js +++ b/app/code/Magento/Customer/view/adminhtml/web/edit/post-wrapper.js @@ -44,12 +44,4 @@ define([ return false; }); - - $('#resetPassword').click(function () { - var url = $('#resetPassword').data('url'); - - getForm(url).appendTo('body').submit(); - - return false; - }); }); diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php index 8fa77a7388be2..789978d8180d0 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php @@ -34,7 +34,7 @@ public function testResetPasswordSuccess() $this->passwordResetRequestEventCreate( \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST ); - $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_GET); $this->dispatch('backend/customer/index/resetPassword'); $this->assertSessionMessages( $this->equalTo(['The customer will receive an email with a link to reset password.']), @@ -44,18 +44,18 @@ public function testResetPasswordSuccess() } /** - * Checks reset password functionality cannot be performed with GET request + * Checks reset password functionality cannot be performed with POST request * * @magentoConfigFixture current_store customer/password/limit_password_reset_requests_method 0 * @magentoConfigFixture current_store customer/password/min_time_between_password_reset_requests 0 * @magentoDataFixture Magento/Customer/_files/customer.php */ - public function testResetPasswordWithGet() + public function testResetPasswordWithPost() { $this->passwordResetRequestEventCreate( \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST ); - $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_GET); + $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_POST); $this->dispatch('backend/customer/index/resetPassword'); $this->assertEquals('noroute', $this->getRequest()->getControllerName()); } @@ -74,7 +74,7 @@ public function testResetPasswordMinTimeError() $this->passwordResetRequestEventCreate( \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST ); - $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_GET); $this->dispatch('backend/customer/index/resetPassword'); $this->assertSessionMessages( $this->equalTo(['The customer will receive an email with a link to reset password.']), @@ -97,7 +97,7 @@ public function testResetPasswordLimitError() $this->passwordResetRequestEventCreate( \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST ); - $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_GET); $this->dispatch('backend/customer/index/resetPassword'); $this->assertSessionMessages( $this->equalTo(['The customer will receive an email with a link to reset password.']), @@ -122,7 +122,7 @@ public function testResetPasswordWithSecurityViolationException() $this->passwordResetRequestEventCreate( \Magento\Security\Model\PasswordResetRequestEvent::ADMIN_PASSWORD_RESET_REQUEST ); - $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue(['customer_id' => '1'])->setMethod(HttpRequest::METHOD_GET); $this->dispatch('backend/customer/index/resetPassword'); $this->assertSessionMessages( $this->equalTo(['The customer will receive an email with a link to reset password.']), From f7be8c8e1cc93bba9a5930ac72c839e7fc0127e4 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 9 Oct 2018 14:45:59 -0500 Subject: [PATCH 231/812] MAGETWO-95532: Unable to upload image from TinyMCE3 --- app/code/Magento/Cms/Model/Wysiwyg/Config.php | 8 +++- .../Tinymce3/Model/Config/Gallery/Config.php | 48 +++++++++++++++++++ app/code/Magento/Tinymce3/composer.json | 2 + .../Magento/Tinymce3/etc/adminhtml/di.xml | 2 +- .../Wysiwyg/CompositeConfigProviderTest.php | 44 +++++++++++++++++ 5 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Tinymce3/Model/Config/Gallery/Config.php create mode 100644 dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php diff --git a/app/code/Magento/Cms/Model/Wysiwyg/Config.php b/app/code/Magento/Cms/Model/Wysiwyg/Config.php index 5db3933dd1169..1da7b99c6d886 100644 --- a/app/code/Magento/Cms/Model/Wysiwyg/Config.php +++ b/app/code/Magento/Cms/Model/Wysiwyg/Config.php @@ -89,8 +89,6 @@ class Config extends \Magento\Framework\DataObject implements ConfigInterface /** * @var array - * @deprecated - * @see \Magento\Cms\Model\Wysiwyg\Gallery\DefaultConfigProvider */ protected $_windowSize; @@ -207,6 +205,12 @@ public function getConfig($data = []) if ($this->_authorization->isAllowed('Magento_Cms::media_gallery')) { $this->configProvider->processGalleryConfig($config); + $config->addData( + [ + 'files_browser_window_width' => $this->_windowSize['width'], + 'files_browser_window_height' => $this->_windowSize['height'], + ] + ); } if ($config->getData('add_widgets')) { $this->configProvider->processWidgetConfig($config); diff --git a/app/code/Magento/Tinymce3/Model/Config/Gallery/Config.php b/app/code/Magento/Tinymce3/Model/Config/Gallery/Config.php new file mode 100644 index 0000000000000..d11a3fa6e8a0c --- /dev/null +++ b/app/code/Magento/Tinymce3/Model/Config/Gallery/Config.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Tinymce3\Model\Config\Gallery; + +/** + * Class Config adds information about required configurations to display media gallery of tinymce3 editor + * + * @deprecated use \Magento\Cms\Model\Wysiwyg\DefaultConfigProvider instead + */ +class Config implements \Magento\Framework\Data\Wysiwyg\ConfigProviderInterface +{ + /** + * @var \Magento\Backend\Model\UrlInterface + */ + private $backendUrl; + + /** + * @param \Magento\Backend\Model\UrlInterface $backendUrl + */ + public function __construct( + \Magento\Backend\Model\UrlInterface $backendUrl + ) { + $this->backendUrl = $backendUrl; + } + + /** + * Returns media gallery config + * + * @param \Magento\Framework\DataObject $config + * @return \Magento\Framework\DataObject + */ + public function getConfig(\Magento\Framework\DataObject $config) : \Magento\Framework\DataObject + { + $config->addData( + [ + 'add_images' => true, + 'files_browser_window_url' => $this->backendUrl->getUrl('cms/wysiwyg_images/index'), + ] + ); + + return $config; + } +} diff --git a/app/code/Magento/Tinymce3/composer.json b/app/code/Magento/Tinymce3/composer.json index 946bfe13f3473..52e980052a87f 100644 --- a/app/code/Magento/Tinymce3/composer.json +++ b/app/code/Magento/Tinymce3/composer.json @@ -4,9 +4,11 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/framework": "*", + "magento/module-backend": "*", "magento/module-ui": "*", "magento/module-variable": "*", "magento/module-widget": "*" + }, "suggest": { "magento/module-cms": "*" diff --git a/app/code/Magento/Tinymce3/etc/adminhtml/di.xml b/app/code/Magento/Tinymce3/etc/adminhtml/di.xml index bf1ec7748294e..53ab66c7ef21f 100644 --- a/app/code/Magento/Tinymce3/etc/adminhtml/di.xml +++ b/app/code/Magento/Tinymce3/etc/adminhtml/di.xml @@ -22,7 +22,7 @@ <item name="Magento_Tinymce3/tinymce3Adapter" xsi:type="string">Magento\Tinymce3\Model\Config\Widget\Config</item> </argument> <argument name="galleryConfigProvider" xsi:type="array"> - <item name="Magento_Tinymce3/tinymce3Adapter" xsi:type="string">Magento\Cms\Model\WysiwygDefaultConfig</item> + <item name="Magento_Tinymce3/tinymce3Adapter" xsi:type="string">Magento\Tinymce3\Model\Config\Gallery\Config</item> </argument> </arguments> </type> diff --git a/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php b/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php new file mode 100644 index 0000000000000..7e60039e86880 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + + +namespace Magento\Tinymce3\Model\Wysiwyg; + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Framework\AuthorizationInterface; + +/** + * @magentoAppArea adminhtml + */ +class CompositeConfigProviderTest extends \PHPUnit\Framework\TestCase +{ + /** + * Test enabled module is able to modify WYSIWYG config + * + * @return void + * + * @magentoConfigFixture default/cms/wysiwyg/editor Magento_Tinymce3/tinymce3Adapter + */ + public function testTestModuleEnabledModuleIsAbleToModifyConfig() + { + $objectManager = Bootstrap::getObjectManager(); + $objectManager->configure([ + 'preferences' => [ + AuthorizationInterface::class => \Magento\Backend\Model\Search\AuthorizationMock::class + ] + ]); + $compositeConfigProvider = $objectManager->create(\Magento\Cms\Model\Wysiwyg\CompositeConfigProvider::class); + $model = $objectManager->create( + \Magento\Cms\Model\Wysiwyg\Config::class, + ['configProvider' => $compositeConfigProvider] + ); + $config = $model->getConfig(); + $this->assertArrayHasKey('add_images', $config); + $this->assertArrayHasKey('files_browser_window_url', $config); + $this->assertTrue($config['add_images']); + } +} From 3a7a1e358f8352f61c587f690850faf8b82b2282 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 9 Oct 2018 16:39:58 -0500 Subject: [PATCH 232/812] MAGETWO-94962: Unable to set default option for swatch attribute --- .../AdminProductAttributeActionGroup.xml | 7 ++++++ .../AdminProductAttributeOptionsSection.xml | 2 +- ...dminCreateDropdownProductAttributeTest.xml | 12 ++++------ ...ateVisualSwatchWithNonValidOptionsTest.xml | 4 +--- .../Adminhtml/Product/AttributeTest.php | 8 +++---- .../Adminhtml/Product/AttributeTest.php | 24 +++++++++---------- 6 files changed, 30 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index 23687484f1012..5de3d40fff9b1 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -20,4 +20,11 @@ <click selector="{{AdminProductAttributeGridSection.FirstRow}}" stepKey="clickOnAttributeRow"/> <waitForPageLoad stepKey="waitForPageLoad2" /> </actionGroup> + <actionGroup name="deleteProductAttribute" extends="navigateToCreatedProductAttribute"> + <click selector="{{AttributePropertiesSection.DeleteAttribute}}" stepKey="deleteAttribute"/> + <click selector="{{ModalConfirmationSection.OkButton}}" stepKey="ClickOnDeleteButton"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <seeElement selector="{{AdminProductMessagesSection.successMessage}}" + stepKey="waitForSuccessMessage"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml index 17ca306eeccfa..0f438540603d0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeOptionsSection.xml @@ -8,7 +8,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="DropdownAttributeOptionsSection"> - <element name="nthAdminLabel" type="input" + <element name="nthOptionAdminLabel" type="input" selector="(//*[@id='manage-options-panel']//tr[{{var}}]//input[contains(@name, 'option[value]')])[1]" parameterized="true"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml index c3e0b22bc5afd..525f81de6c48c 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeTest.xml @@ -12,7 +12,7 @@ <stories value="Create/configure Dropdown product attribute"/> <title value="Admin should be able to create dropdown product attribute"/> <description value="Admin should be able to create dropdown product attribute"/> - <severity value="BLOCKER"/> + <severity value="CRITICAL"/> <testCaseId value="MC-4982"/> <group value="Catalog"/> </annotations> @@ -21,11 +21,9 @@ </before> <after> <!-- Remove attribute --> - <actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute"> + <actionGroup ref="deleteProductAttribute" stepKey="deleteAttribute"> <argument name="ProductAttribute" value="productDropDownAttribute"/> </actionGroup> - <click selector="{{AttributePropertiesSection.DeleteAttribute}}" stepKey="deleteAttribute"/> - <actionGroup ref="logout" stepKey="logout"/> </after> @@ -49,11 +47,11 @@ <!-- Add new attribute options --> <click selector="{{AttributeOptionsSection.AddOption}}" stepKey="clickAddOption1"/> - <fillField selector="{{DropdownAttributeOptionsSection.nthAdminLabel('1')}}" + <fillField selector="{{DropdownAttributeOptionsSection.nthOptionAdminLabel('1')}}" userInput="Fish and Chips" stepKey="fillAdminValue1"/> <click selector="{{AttributeOptionsSection.AddOption}}" stepKey="clickAddOption2"/> - <fillField selector="{{DropdownAttributeOptionsSection.nthAdminLabel('2')}}" + <fillField selector="{{DropdownAttributeOptionsSection.nthOptionAdminLabel('2')}}" userInput="Fish & Chips" stepKey="fillAdminValue2"/> <!-- Save the new product attribute --> @@ -66,7 +64,7 @@ <argument name="ProductAttribute" value="productDropDownAttribute"/> </actionGroup> <!-- Check attribute data --> - <grabValueFrom selector="{{DropdownAttributeOptionsSection.nthAdminLabel('2')}}" + <grabValueFrom selector="{{DropdownAttributeOptionsSection.nthOptionAdminLabel('2')}}" stepKey="secondOptionAdminLabel"/> <assertEquals actual="$secondOptionAdminLabel" expected="'Fish & Chips'" stepKey="assertSecondOption"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml index 5d174e71012fd..b03f771875957 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchWithNonValidOptionsTest.xml @@ -21,11 +21,9 @@ </before> <after> <!-- Remove attribute --> - <actionGroup ref="navigateToCreatedProductAttribute" stepKey="navigateToAttribute"> + <actionGroup ref="deleteProductAttribute" stepKey="deleteAttribute"> <argument name="ProductAttribute" value="visualSwatchAttribute"/> </actionGroup> - <click selector="{{AttributePropertiesSection.DeleteAttribute}}" stepKey="deleteAttribute"/> - <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php index 101e9f596be52..ab8c29889eabd 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php @@ -302,10 +302,10 @@ public function testLargeOptionsDataSet() $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; $optionId = 'option_' . $i; $optionRowData = []; - $optionRowData["option"]["order"][$optionId] = $i + 1; - $optionRowData["option"]["value"][$optionId][0] = 'value_' . $i . '_admin'; - $optionRowData["option"]["value"][$optionId][1] = $expectedOptionLabelOnStoreView; - $optionRowData["option"]["delete"][$optionId] = ''; + $optionRowData['option']['order'][$optionId] = $i + 1; + $optionRowData['option']['value'][$optionId][0] = 'value_' . $i . '_admin'; + $optionRowData['option']['value'][$optionId][1] = $expectedOptionLabelOnStoreView; + $optionRowData['option']['delete'][$optionId] = ''; $optionsData[] = http_build_query($optionRowData); } $attributeData['serialized_options'] = json_encode($optionsData); diff --git a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php index 10f6703f583d7..f806674d29705 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/Controller/Adminhtml/Product/AttributeTest.php @@ -59,12 +59,12 @@ private function getSwatchVisualDataSet(int $optionsCount) : array $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; $optionId = 'option_' .$i; $optionRowData = []; - $optionRowData["optionvisual"]["order"][$optionId] = $i + 1; - $optionRowData["defaultvisual"][] = $optionId; - $optionRowData["swatchvisual"]["value"][$optionId] = $this->getRandomColor(); - $optionRowData["optionvisual"]["value"][$optionId][0] = 'value_' . $i .'_admin'; - $optionRowData["optionvisual"]["value"][$optionId][1] = $expectedOptionLabelOnStoreView; - $optionRowData["optionvisual"]["delete"][$optionId] = ''; + $optionRowData['optionvisual']['order'][$optionId] = $i + 1; + $optionRowData['defaultvisual'][] = $optionId; + $optionRowData['swatchvisual']['value'][$optionId] = $this->getRandomColor(); + $optionRowData['optionvisual']['value'][$optionId][0] = 'value_' . $i .'_admin'; + $optionRowData['optionvisual']['value'][$optionId][1] = $expectedOptionLabelOnStoreView; + $optionRowData['optionvisual']['delete'][$optionId] = ''; $optionsData[] = http_build_query($optionRowData); } return [ @@ -101,12 +101,12 @@ private function getSwatchTextDataSet(int $optionsCount) : array $expectedOptionsLabels[$i+1] = $expectedOptionLabelOnStoreView; $optionId = 'option_' . $i; $optionRowData = []; - $optionRowData["optiontext"]["order"][$optionId] = $i + 1; - $optionRowData["defaulttext"][] = $optionId; - $optionRowData["swatchtext"]["value"][$optionId] = 'x' . $i ; - $optionRowData["optiontext"]["value"][$optionId][0] = 'value_' . $i . '_admin'; - $optionRowData["optiontext"]["value"][$optionId][1]= $expectedOptionLabelOnStoreView; - $optionRowData["optiontext"]["delete"][$optionId]=''; + $optionRowData['optiontext']['order'][$optionId] = $i + 1; + $optionRowData['defaulttext'][] = $optionId; + $optionRowData['swatchtext']['value'][$optionId] = 'x' . $i ; + $optionRowData['optiontext']['value'][$optionId][0] = 'value_' . $i . '_admin'; + $optionRowData['optiontext']['value'][$optionId][1]= $expectedOptionLabelOnStoreView; + $optionRowData['optiontext']['delete'][$optionId]=''; $optionsData[] = http_build_query($optionRowData); } return [ From 77111659b520ebad13b53389f67144fddd5dfad6 Mon Sep 17 00:00:00 2001 From: Thiago Lima <thiagolimaufrj@gmail.com> Date: Wed, 10 Oct 2018 11:28:17 +0200 Subject: [PATCH 233/812] 18082 fix unit test --- .../Product/Initialization/Helper/Plugin/Configurable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php index 556939ec112f1..b5940e36aa792 100644 --- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Configurable.php @@ -158,7 +158,7 @@ protected function getVariationMatrix() $configurableMatrix = json_decode($configurableMatrix, true); foreach ($configurableMatrix as $item) { - if (isset($item['newProduct'])) { + if (isset($item['newProduct']) && $item['newProduct']) { $result[$item['variationKey']] = $this->mapData($item); if (isset($item['qty'])) { From 9b2aeaae00187adf4fda25657757886d7f1a81d1 Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Wed, 10 Oct 2018 13:15:26 +0300 Subject: [PATCH 234/812] MAGETWO-95313: [2.3] Missing URL Keys upon product import --- .../Model/Import/Product.php | 32 ++++++++++++++- .../Model/Import/ProductTest.php | 39 +++++++++++++++++++ ...ts_to_import_without_url_keys_and_name.csv | 3 ++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_without_url_keys_and_name.csv diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 7c56c266a64ef..2aae8fd808528 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -1640,7 +1640,16 @@ protected function _saveProducts() } $rowScope = $this->getRowScope($rowData); - $rowData[self::URL_KEY] = $this->getUrlKey($rowData); + $urlKey = $this->getUrlKey($rowData); + if (!empty($rowData[self::URL_KEY])) { + // If url_key column and its value were in the CSV file + $rowData[self::URL_KEY] = $urlKey; + } else if($this->isNeedToChangeUrlKey($rowData)) { + // If url_key column was empty or even not declared in the CSV file but by the rules it is need to + // be setteed. In case when url_key is generating from name column we have to ensure that the bunch + // of products will pass for the event with url_key column. + $bunch[$rowNum][self::URL_KEY] = $rowData[self::URL_KEY] = $urlKey; + } $rowSku = $rowData[self::COL_SKU]; @@ -2889,6 +2898,27 @@ protected function getResource() return $this->_resource; } + /** + * Whether a url key is needed to be change. + * Returns false if + * + * @param array $rowData + * @return bool + */ + private function isNeedToChangeUrlKey(array $rowData): bool + { + $urlKey = $this->getUrlKey($rowData); + $productExists = $this->isSkuExist($rowData[self::COL_SKU]); + $markedToEraseUrlKey = isset($rowData[self::URL_KEY]); + // The product isn't new and the url key index wasn't marked for change. + if (!$urlKey && $productExists && !$markedToEraseUrlKey) { + // Seems there is no need to change the url key + return false; + } + + return true; + } + /** * Get product entity link field * diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 237d7660da9bd..0286cc184f0d5 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -1643,6 +1643,45 @@ public function testImportWithoutUrlKeys() } } + /** + * Make sure the absence of a url_key column in the csv file won't erase the url key of the existing products. + * To reach the goal we need to not send the name column, as the url key is generated from it. + * + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php + * @magentoDbIsolation disabled + * @magentoAppIsolation enabled + */ + public function testImportWithoutUrlKeysAndName() + { + $products = [ + 'simple1' => 'url-key', + 'simple2' => 'url-key2', + ]; + $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class); + $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); + $source = $this->objectManager->create( + \Magento\ImportExport\Model\Import\Source\Csv::class, + [ + 'file' => __DIR__ . '/_files/products_to_import_without_url_keys_and_name.csv', + 'directory' => $directory + ] + ); + + $errors = $this->_model->setParameters( + ['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product'] + ) + ->setSource($source) + ->validateData(); + + $this->assertTrue($errors->getErrorsCount() == 0); + $this->_model->importData(); + + $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + foreach ($products as $productSku => $productUrlKey) { + $this->assertEquals($productUrlKey, $productRepository->get($productSku)->getUrlKey()); + } + } + /** * @magentoAppIsolation enabled */ diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_without_url_keys_and_name.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_without_url_keys_and_name.csv new file mode 100644 index 0000000000000..8ea6ab92a0295 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_without_url_keys_and_name.csv @@ -0,0 +1,3 @@ +sku,price +simple1,25 +simple2,34 From b0d7a268162d57f3f30a3488fca1afac104ae322 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Wed, 10 Oct 2018 13:53:30 +0300 Subject: [PATCH 235/812] MAGETWO-91679: Bundled SKUs are being assembled based on the product ID number - Integration test fix --- app/code/Magento/Bundle/Model/Product/Type.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php index 67441cd944c4f..3729cd945758f 100644 --- a/app/code/Magento/Bundle/Model/Product/Type.php +++ b/app/code/Magento/Bundle/Model/Product/Type.php @@ -310,7 +310,7 @@ public function getSku($product) $selections = $this->getSelectionsByIds($selectionIds, $product); foreach ($selectionIds as $selectionId) { $entity = $selections->getItemByColumnValue('selection_id', $selectionId); - if ($entity->getEntityId()) { + if (isset($entity) && $entity->getEntityId()) { $skuParts[] = $entity->getSku(); } } From adb976306df15159bcc612b03ee962fa61ea465a Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Wed, 10 Oct 2018 15:05:02 +0300 Subject: [PATCH 236/812] MAGETWO-95313: [2.3] Missing URL Keys upon product import --- .../Magento/CatalogImportExport/Model/Import/Product.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 2aae8fd808528..6f8b2248d8d89 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -1641,10 +1641,10 @@ protected function _saveProducts() $rowScope = $this->getRowScope($rowData); $urlKey = $this->getUrlKey($rowData); - if (!empty($rowData[self::URL_KEY])) { + if (!empty($rowData[self::URL_KEY])) { // If url_key column and its value were in the CSV file $rowData[self::URL_KEY] = $urlKey; - } else if($this->isNeedToChangeUrlKey($rowData)) { + } else if ($this->isNeedToChangeUrlKey($rowData)) { // If url_key column was empty or even not declared in the CSV file but by the rules it is need to // be setteed. In case when url_key is generating from name column we have to ensure that the bunch // of products will pass for the event with url_key column. @@ -2900,7 +2900,6 @@ protected function getResource() /** * Whether a url key is needed to be change. - * Returns false if * * @param array $rowData * @return bool From 87581cf49114445da5ac91b857c8415f5ffd0ab9 Mon Sep 17 00:00:00 2001 From: avattam <> Date: Wed, 10 Oct 2018 07:22:46 -0500 Subject: [PATCH 237/812] MAGETWO-95111: Creating new store view with code uniqueness validation - added functional test to cover the bug fix --- .../Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml index 99ca7991e5e90..6ce33f3be3622 100644 --- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml @@ -24,6 +24,7 @@ <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> + <waitForPageLoad stepKey="waitForPageLoad2" /> <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" stepKey="waitForPageReolad"/> <see userInput="You saved the store view." stepKey="seeSavedMessage" /> </actionGroup> From 38dadb1f19dfa304083c019ba619ccda4bb44426 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 10 Oct 2018 16:11:33 +0300 Subject: [PATCH 238/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Magento/Backend/view/adminhtml/web/js/media-uploader.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js index 6789dfa3f2b8e..e1d5a0a9debe5 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js +++ b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js @@ -135,8 +135,7 @@ define([ this.element.find('input[type=file]').fileupload('option', { process: [{ action: 'load', - fileTypes: /^image\/(gif|jpeg|png)$/, - maxFileSize: this.options.maxFileSize + fileTypes: /^image\/(gif|jpeg|png)$/ }, resizeConfiguration, { From 9c19879740e5493eebf6b8e308cc57a26ac07eb1 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Wed, 10 Oct 2018 17:35:40 +0300 Subject: [PATCH 239/812] MAGETWO-91725: Reward Points Balance Update Emails are not being sent when balance change initiated by store front - Bug fix - Integration test fix --- .../Model/Metadata/CustomerMetadata.php | 27 +++++++++---------- app/code/Magento/Customer/etc/di.xml | 7 +++++ .../Customer/Model/CustomerMetadataTest.php | 19 ++++++++----- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php b/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php index 7e8f0b9236fe9..38f3fbcbdbded 100644 --- a/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php +++ b/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php @@ -33,16 +33,26 @@ class CustomerMetadata implements CustomerMetadataInterface */ private $attributeMetadataDataProvider; + /** + * List of system attributes which should be available to the clients. + * + * @var string[] + */ + private $systemAttributes; + /** * @param AttributeMetadataConverter $attributeMetadataConverter * @param AttributeMetadataDataProvider $attributeMetadataDataProvider + * @param string[] $systemAttributes */ public function __construct( AttributeMetadataConverter $attributeMetadataConverter, - AttributeMetadataDataProvider $attributeMetadataDataProvider + AttributeMetadataDataProvider $attributeMetadataDataProvider, + array $systemAttributes = [] ) { $this->attributeMetadataConverter = $attributeMetadataConverter; $this->attributeMetadataDataProvider = $attributeMetadataDataProvider; + $this->systemAttributes = $systemAttributes; } /** @@ -136,7 +146,7 @@ public function getCustomAttributesMetadata($dataObjectClassName = self::DATA_IN if (!$isDataObjectMethod && (!$attributeMetadata->isSystem() - || in_array($attributeCode, $this->getAllowedSystemAttributesList()) + || in_array($attributeCode, $this->systemAttributes) ) ) { $customAttributes[] = $attributeMetadata; @@ -144,17 +154,4 @@ public function getCustomAttributesMetadata($dataObjectClassName = self::DATA_IN } return $customAttributes; } - - /** - * Get list of system attributes which should be available to the clients - * - * @return array - */ - private function getAllowedSystemAttributesList() - { - return [ - 'disable_auto_group_change', - 'reward_update_notification' - ]; - } } diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index 6e8c3dc68ed28..209f4794c6fcf 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -127,6 +127,13 @@ <argument name="groupManagement" xsi:type="object">Magento\Customer\Api\GroupManagementInterface\Proxy</argument> </arguments> </type> + <type name="Magento\Customer\Model\Metadata\CustomerMetadata"> + <arguments> + <argument name="systemAttributes" xsi:type="array"> + <item name="disable_auto_group_change" xsi:type="string">disable_auto_group_change</item> + </argument> + </arguments> + </type> <virtualType name="SectionInvalidationConfigReader" type="Magento\Framework\Config\Reader\Filesystem"> <arguments> <argument name="idAttributes" xsi:type="array"> diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php index 336b438661705..794fce17480fa 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php @@ -51,16 +51,23 @@ protected function setUp() public function testGetCustomAttributesMetadata() { - $customAttributesMetadata = $this->service->getCustomAttributesMetadata(); - $this->assertCount(0, $customAttributesMetadata, "Invalid number of attributes returned."); + $customAttributesMetadataQty = count($this->service->getCustomAttributesMetadata()) ; // Verify the consistency of getCustomerAttributeMetadata() function from the 2nd call of the same service - $customAttributesMetadata1 = $this->service->getCustomAttributesMetadata(); - $this->assertCount(0, $customAttributesMetadata1, "Invalid number of attributes returned."); + $customAttributesMetadata1Qty = count($this->service->getCustomAttributesMetadata()); + $this->assertEquals( + $customAttributesMetadataQty, + $customAttributesMetadata1Qty, + "Invalid number of attributes returned." + ); // Verify the consistency of getCustomAttributesMetadata() function from the 2nd service - $customAttributesMetadata2 = $this->serviceTwo->getCustomAttributesMetadata(); - $this->assertCount(0, $customAttributesMetadata2, "Invalid number of attributes returned."); + $customAttributesMetadata2Qty = count($this->serviceTwo->getCustomAttributesMetadata()); + $this->assertEquals( + $customAttributesMetadataQty, + $customAttributesMetadata2Qty, + "Invalid number of attributes returned." + ); } public function testGetNestedOptionsCustomerAttributesMetadata() From cb15e6086ab62c76b02770ff2f15a3c9665b7eaa Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Wed, 10 Oct 2018 17:54:52 +0300 Subject: [PATCH 240/812] MAGETWO-92163: Redundancy in Custom Option Filenames --- .../Option/Type/File/ExistingValidate.php | 50 ++++ .../Option/Type/File/ValidateFactory.php | 2 +- .../Option/Type/File/ValidatorFile.php | 18 +- .../Option/Type/File/ValidatorInfo.php | 5 +- app/code/Magento/Sales/Model/Download.php | 3 +- .../Sales/Test/Unit/Model/DownloadTest.php | 262 ------------------ .../Controller/Index/DownloadCustomOption.php | 3 +- .../Index/DownloadCustomOptionTest.php | 154 ---------- .../Option/Type/File/ValidatorFileTest.php | 17 +- 9 files changed, 86 insertions(+), 428 deletions(-) create mode 100644 app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php delete mode 100644 app/code/Magento/Sales/Test/Unit/Model/DownloadTest.php delete mode 100644 app/code/Magento/Wishlist/Test/Unit/Controller/Index/DownloadCustomOptionTest.php diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php new file mode 100644 index 0000000000000..8d4aea135eabb --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Model\Product\Option\Type\File; + +/** + * Validator for existing (already saved) files. + */ +class ExistingValidate extends \Zend_Validate +{ + /** + * @inheritDoc + * + * @param string $value File's full path. + * @param string|null $originalName Original file's name (when uploaded). + */ + public function isValid($value, string $originalName = null) + { + $this->_messages = []; + $this->_errors = []; + + if (!is_string($value)) { + $this->_messages[] = __('Full file path is expected.')->render(); + return false; + } + + $result = true; + $fileInfo = null; + if ($originalName) { + $fileInfo = ['name' => $originalName]; + } + foreach ($this->_validators as $element) { + $validator = $element['instance']; + if ($validator->isValid($value, $fileInfo)) { + continue; + } + $result = false; + $messages = $validator->getMessages(); + $this->_messages = array_merge($this->_messages, $messages); + $this->_errors = array_merge($this->_errors, array_keys($messages)); + if ($element['breakChainOnFailure']) { + break; + } + } + return $result; + } +} diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php index 32c901afe8e74..c0d10c720f6f6 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php @@ -13,6 +13,6 @@ class ValidateFactory */ public function create() { - return new \Zend_Validate(); + return new ExistingValidate(); } } diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php index d6a5cb1cbc29d..7449c9ea78883 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php @@ -10,6 +10,8 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Catalog\Model\Product\Exception as ProductException; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Math\Random; +use Magento\Framework\App\ObjectManager; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -62,12 +64,18 @@ class ValidatorFile extends Validator */ protected $isImageValidator; + /** + * @var Random + */ + private $random; + /** * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Framework\File\Size $fileSize * @param \Magento\Framework\HTTP\Adapter\FileTransferFactory $httpFactory * @param \Magento\Framework\Validator\File\IsImage $isImageValidator + * @param Random|null $random * @throws \Magento\Framework\Exception\FileSystemException */ public function __construct( @@ -75,12 +83,15 @@ public function __construct( \Magento\Framework\Filesystem $filesystem, \Magento\Framework\File\Size $fileSize, \Magento\Framework\HTTP\Adapter\FileTransferFactory $httpFactory, - \Magento\Framework\Validator\File\IsImage $isImageValidator + \Magento\Framework\Validator\File\IsImage $isImageValidator, + Random $random = null ) { $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->filesystem = $filesystem; $this->httpFactory = $httpFactory; $this->isImageValidator = $isImageValidator; + $this->random = $random + ?? ObjectManager::getInstance()->get(Random::class); parent::__construct($scopeConfig, $filesystem, $fileSize); } @@ -154,8 +165,6 @@ public function validate($processingParams, $option) $userValue = []; if ($upload->isUploaded($file) && $upload->isValid($file)) { - $extension = pathinfo(strtolower($fileInfo['name']), PATHINFO_EXTENSION); - $fileName = \Magento\MediaStorage\Model\File\Uploader::getCorrectFileName($fileInfo['name']); $dispersion = \Magento\MediaStorage\Model\File\Uploader::getDispersionPath($fileName); @@ -163,7 +172,8 @@ public function validate($processingParams, $option) $tmpDirectory = $this->filesystem->getDirectoryRead(DirectoryList::SYS_TMP); $fileHash = md5($tmpDirectory->readFile($tmpDirectory->getRelativePath($fileInfo['tmp_name']))); - $filePath .= '/' . $fileHash . '.' . $extension; + $fileRandomName = $this->random->getRandomString(32); + $filePath .= '/' .$fileRandomName; $fileFullPath = $this->mediaDirectory->getAbsolutePath($this->quotePath . $filePath); $upload->addFilter(new \Zend_Filter_File_Rename(['target' => $fileFullPath, 'overwrite' => true])); diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php index 37e4c7b310a81..31e89d424e3b2 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php @@ -6,6 +6,9 @@ namespace Magento\Catalog\Model\Product\Option\Type\File; +/** + * Validator for existing files. + */ class ValidatorInfo extends Validator { /** @@ -90,7 +93,7 @@ public function validate($optionValue, $option) } $result = false; - if ($validatorChain->isValid($this->fileFullPath)) { + if ($validatorChain->isValid($this->fileFullPath, $optionValue['title'])) { $result = $this->rootDirectory->isReadable($this->fileRelativePath) && isset($optionValue['secret_key']) && $this->buildSecretKey($this->fileRelativePath) == $optionValue['secret_key']; diff --git a/app/code/Magento/Sales/Model/Download.php b/app/code/Magento/Sales/Model/Download.php index 6d3ad8491253a..14395bb9afedd 100644 --- a/app/code/Magento/Sales/Model/Download.php +++ b/app/code/Magento/Sales/Model/Download.php @@ -78,7 +78,8 @@ public function downloadFile($info) $this->_fileFactory->create( $info['title'], ['value' => $this->_rootDir->getRelativePath($relativePath), 'type' => 'filename'], - $this->rootDirBasePath + $this->rootDirBasePath, + $info['type'] ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/DownloadTest.php b/app/code/Magento/Sales/Test/Unit/Model/DownloadTest.php deleted file mode 100644 index dd430f8a03304..0000000000000 --- a/app/code/Magento/Sales/Test/Unit/Model/DownloadTest.php +++ /dev/null @@ -1,262 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Sales\Test\Unit\Model; - -use Magento\Framework\App\Filesystem\DirectoryList; - -class DownloadTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Sales\Model\Download - */ - protected $model; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $filesystemMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $storageMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $storageFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $httpFileFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $writeDirectoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $driverMock; - - protected function setUp() - { - $this->writeDirectoryMock = $this->getMockBuilder(\Magento\Framework\Filesystem\Directory\Write::class) - ->disableOriginalConstructor() - ->getMock(); - $this->filesystemMock = $this->getMockBuilder(\Magento\Framework\Filesystem::class) - ->disableOriginalConstructor() - ->getMock(); - $this->filesystemMock->expects($this->any()) - ->method('getDirectoryWrite') - ->with(DirectoryList::MEDIA) - ->will($this->returnValue($this->writeDirectoryMock)); - - $this->driverMock = $this->getMockForAbstractClass(\Magento\Framework\Filesystem\DriverInterface::class); - $this->storageMock = $this->getMockBuilder(\Magento\MediaStorage\Helper\File\Storage\Database::class) - ->disableOriginalConstructor() - ->getMock(); - $this->storageFactoryMock = $this->getMockBuilder( - \Magento\MediaStorage\Model\File\Storage\DatabaseFactory::class - )->disableOriginalConstructor() - ->setMethods(['create', 'checkDbUsage']) - ->getMock(); - $this->httpFileFactoryMock = $this->getMockBuilder(\Magento\Framework\App\Response\Http\FileFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $this->model = new \Magento\Sales\Model\Download( - $this->filesystemMock, - $this->storageMock, - $this->storageFactoryMock, - $this->httpFileFactoryMock - ); - } - - public function testInstanceOf() - { - $model = new \Magento\Sales\Model\Download( - $this->filesystemMock, - $this->storageMock, - $this->storageFactoryMock, - $this->httpFileFactoryMock - ); - $this->assertInstanceOf(\Magento\Sales\Model\Download::class, $model); - } - - /** - * @param $realPatchCheck - * @param $isFile - * @param $isReadable - * @expectedException \Magento\Framework\Exception\LocalizedException - * @dataProvider dataProviderForTestDownloadFileException - */ - public function testDownloadFileException($realPatchCheck, $isFile, $isReadable) - { - $info = ['order_path' => 'test/path', 'quote_path' => 'test/path2', 'title' => 'test title']; - - $this->writeDirectoryMock->expects($this->any()) - ->method('getAbsolutePath') - ->will($this->returnArgument(0)); - $this->writeDirectoryMock->expects($this->any()) - ->method('getDriver') - ->willReturn($this->driverMock); - $this->driverMock->expects($this->any())->method('getRealPath')->willReturn($realPatchCheck); - $this->writeDirectoryMock->expects($this->any()) - ->method('isFile') - ->will($this->returnValue($isFile)); - $this->writeDirectoryMock->expects($this->any()) - ->method('isReadable') - ->will($this->returnValue($isReadable)); - - $this->storageFactoryMock->expects($this->any()) - ->method('checkDbUsage') - ->will($this->returnValue(false)); - $this->httpFileFactoryMock->expects($this->never())->method('create'); - - $this->model->downloadFile($info); - } - - /** - * @return array - */ - public function dataProviderForTestDownloadFileException() - { - return [ - [1, true, false], - [1, false, true], - [false, true, true], - ]; - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testDownloadFileNoStorage() - { - $info = ['order_path' => 'test/path', 'quote_path' => 'test/path2', 'title' => 'test title']; - $isFile = true; - $isReadable = false; - - $this->writeDirectoryMock->expects($this->any()) - ->method('getAbsolutePath') - ->will($this->returnArgument(0)); - $this->writeDirectoryMock->expects($this->any()) - ->method('getDriver') - ->willReturn($this->driverMock); - $this->driverMock->expects($this->any())->method('getRealPath')->willReturn(true); - - $this->writeDirectoryMock->expects($this->any()) - ->method('isFile') - ->will($this->returnValue($isFile)); - $this->writeDirectoryMock->expects($this->any()) - ->method('isReadable') - ->will($this->returnValue($isReadable)); - - $this->storageMock->expects($this->any()) - ->method('checkDbUsage') - ->will($this->returnValue(true)); - - $storageDatabaseMock = $this->getMockBuilder(\Magento\MediaStorage\Model\File\Storage\Database::class) - ->disableOriginalConstructor() - ->getMock(); - $storageDatabaseMock->expects($this->at(0)) - ->method('loadByFilename') - ->with($this->equalTo($info['order_path'])) - ->will($this->returnSelf()); - $storageDatabaseMock->expects($this->at(2)) - ->method('loadByFilename') - ->with($this->equalTo($info['quote_path'])) - ->will($this->returnSelf()); - - $storageDatabaseMock->expects($this->any()) - ->method('getId') - ->will($this->returnValue(false)); - - $this->storageFactoryMock->expects($this->any()) - ->method('create') - ->will($this->returnValue($storageDatabaseMock)); - $this->httpFileFactoryMock->expects($this->never())->method('create'); - - $this->model->downloadFile($info); - } - - public function testDownloadFile() - { - $info = ['order_path' => 'test/path', 'quote_path' => 'test/path2', 'title' => 'test title']; - $isFile = true; - $isReadable = false; - - $writeMock = $this->getMockBuilder(\Magento\Framework\Filesystem\File\Write::class) - ->disableOriginalConstructor() - ->getMock(); - $writeMock->expects($this->any()) - ->method('lock'); - $writeMock->expects($this->any()) - ->method('write'); - $writeMock->expects($this->any()) - ->method('unlock'); - $writeMock->expects($this->any()) - ->method('close'); - - $this->writeDirectoryMock->expects($this->any()) - ->method('getAbsolutePath') - ->will($this->returnArgument(0)); - $this->writeDirectoryMock->expects($this->any()) - ->method('getDriver') - ->willReturn($this->driverMock); - $this->driverMock->expects($this->any())->method('getRealPath')->willReturn(true); - - $this->writeDirectoryMock->expects($this->any()) - ->method('isFile') - ->will($this->returnValue($isFile)); - $this->writeDirectoryMock->expects($this->any()) - ->method('isReadable') - ->will($this->returnValue($isReadable)); - $this->writeDirectoryMock->expects($this->any()) - ->method('openFile') - ->will($this->returnValue($writeMock)); - $this->writeDirectoryMock->expects($this->once()) - ->method('getRelativePath') - ->with($info['order_path']) - ->will($this->returnArgument(0)); - - $this->storageMock->expects($this->any()) - ->method('checkDbUsage') - ->will($this->returnValue(true)); - - $storageDatabaseMock = $this->getMockBuilder(\Magento\MediaStorage\Model\File\Storage\Database::class) - ->disableOriginalConstructor() - ->setMethods(['loadByFilename', 'getId', '__wakeup']) - ->getMock(); - $storageDatabaseMock->expects($this->any()) - ->method('loadByFilename') - ->will($this->returnSelf()); - - $storageDatabaseMock->expects($this->any()) - ->method('getId') - ->will($this->returnValue(true)); - - $this->storageFactoryMock->expects($this->any()) - ->method('create') - ->will($this->returnValue($storageDatabaseMock)); - - $this->httpFileFactoryMock->expects($this->once()) - ->method('create') - ->with( - $info['title'], - ['value' => $info['order_path'], 'type' => 'filename'], - DirectoryList::MEDIA, - 'application/octet-stream', - null - ); - - $result = $this->model->downloadFile($info); - $this->assertNull($result); - } -} diff --git a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php index e43a03e72d87c..095e64ddf7620 100644 --- a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php +++ b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php @@ -92,7 +92,8 @@ public function execute() $this->_fileResponseFactory->create( $info['title'], ['value' => $info['quote_path'], 'type' => 'filename'], - DirectoryList::ROOT + DirectoryList::ROOT, + $info['type'] ); } } catch (\Exception $e) { diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/DownloadCustomOptionTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/DownloadCustomOptionTest.php deleted file mode 100644 index 6fefe18cf8975..0000000000000 --- a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/DownloadCustomOptionTest.php +++ /dev/null @@ -1,154 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Wishlist\Test\Unit\Controller\Index; - -class DownloadCustomOptionTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Wishlist\Controller\Index\DownloadCustomOption - */ - protected $model; - - /** - * @var \Magento\Framework\App\Action\Context|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contextMock; - - /** - * @var \Magento\Framework\App\Response\Http\FileFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $fileResponseFactoryMock; - - /** - * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $requestMock; - - /** - * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $objectManagerMock; - - /** - * @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $resultFactoryMock; - - /** - * @var \Magento\Framework\Serialize\Serializer\Json|\PHPUnit_Framework_MockObject_MockObject - */ - protected $jsonMock; - - protected function setUp() - { - $this->fileResponseFactoryMock = $this->getMockBuilder(\Magento\Framework\App\Response\Http\FileFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->jsonMock = $this->getMockBuilder(\Magento\Framework\Serialize\Serializer\Json::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class) - ->disableOriginalConstructor() - ->setMethods(['create', 'get', 'configure']) - ->getMock(); - - $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->resultFactoryMock = $this->getMockBuilder(\Magento\Framework\Controller\ResultFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->contextMock = $this->getMockBuilder(\Magento\Framework\App\Action\Context::class) - ->disableOriginalConstructor() - ->getMock(); - $this->contextMock->expects($this->any()) - ->method('getObjectManager') - ->willReturn($this->objectManagerMock); - $this->contextMock->expects($this->any()) - ->method('getRequest') - ->willReturn($this->requestMock); - $this->contextMock->expects($this->any()) - ->method('getResultFactory') - ->willReturn($this->resultFactoryMock); - - $this->model = new \Magento\Wishlist\Controller\Index\DownloadCustomOption( - $this->contextMock, - $this->fileResponseFactoryMock, - $this->jsonMock - ); - } - - public function testExecute() - { - $data = [ - 'number' => 42, - 'string' => 'string_value', - 'boolean' => true, - 'collection' => [1, 2, 3], - 'secret_key' => 999 - ]; - $serialized_data = json_encode($data); - - $optionMock = $this->getMockBuilder(\Magento\Wishlist\Model\Item\Option::class) - ->disableOriginalConstructor() - ->setMethods(['getProductId', 'load', 'getId', 'getValue']) - ->getMock(); - $optionMock->expects($this->any()) - ->method('load') - ->willReturnSelf(); - $optionMock->expects($this->any()) - ->method('getId') - ->willReturn(true); - $optionMock->expects($this->any()) - ->method('getProductId') - ->willReturn('some_value'); - $optionMock->expects($this->any()) - ->method('getValue') - ->willReturn($serialized_data); - - $productOptionMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Option::class) - ->disableOriginalConstructor() - ->setMethods(['getProductId', 'load', 'getId', 'getType']) - ->getMock(); - $productOptionMock->expects($this->any()) - ->method('load') - ->willReturnSelf(); - $productOptionMock->expects($this->any()) - ->method('getId') - ->willReturn(true); - $productOptionMock->expects($this->any()) - ->method('getProductId') - ->willReturn('some_value'); - $productOptionMock->expects($this->any()) - ->method('getType') - ->willReturn('file'); - - $this->objectManagerMock->expects($this->any()) - ->method('create') - ->willReturnMap( - [ - [\Magento\Wishlist\Model\Item\Option::class, [], $optionMock], - [\Magento\Catalog\Model\Product\Option::class, [], $productOptionMock] - ] - ); - - $this->requestMock->expects($this->any()) - ->method('getParam') - ->willReturn(1); - - $this->jsonMock->expects($this->once()) - ->method('unserialize') - ->willReturnCallback(function ($value) { - return json_decode($value, true); - }); - - $this->assertEquals(null, $this->model->execute()); - } -} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFileTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFileTest.php index e7a2d17586a93..37ef60208861d 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFileTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFileTest.php @@ -6,6 +6,8 @@ namespace Magento\Catalog\Model\Product\Option\Type\File; +use Magento\Framework\Math\Random; + /** * @magentoDataFixture Magento/Catalog/_files/validate_image.php * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -48,11 +50,18 @@ protected function setUp() $fileSize = $this->objectManager->create(\Magento\Framework\File\Size::class); $this->maxFileSize = $fileSize->getMaxFileSize(); $this->maxFileSizeInMb = $fileSize->getMaxFileSizeInMb(); + $random = $this->getMockBuilder(Random::class) + ->disableOriginalConstructor() + ->getMock(); + $random->expects($this->any()) + ->method('getRandomString') + ->willReturn('RandomString'); $this->model = $this->objectManager->create( - \Magento\Catalog\Model\Product\Option\Type\File\ValidatorFile::class, + ValidatorFile::class, [ - 'httpFactory' => $this->httpFactoryMock + 'httpFactory' => $this->httpFactoryMock, + 'random' => $random, ] ); } @@ -350,8 +359,8 @@ protected function expectedValidate() return [ 'type' => 'image/jpeg', 'title' => 'test.jpg', - 'quote_path' => 'custom_options/quote/t/e/a071b9ffc8fda6df1652c05a4c61bf8a.jpg', - 'order_path' => 'custom_options/order/t/e/a071b9ffc8fda6df1652c05a4c61bf8a.jpg', + 'quote_path' => 'custom_options/quote/t/e/RandomString', + 'order_path' => 'custom_options/order/t/e/RandomString', 'size' => '3046', 'width' => 136, 'height' => 131, From 4279e3e7dcb3192356e4e9a23edf15858f641864 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Wed, 10 Oct 2018 17:57:54 +0300 Subject: [PATCH 241/812] MAGETWO-92163: Redundancy in Custom Option Filenames --- .../Model/Product/Option/Type/File/ValidateFactory.php | 5 +++++ .../Model/Product/Option/Type/File/ValidatorFile.php | 10 ++++++++++ .../Model/Product/Option/Type/File/ValidatorInfo.php | 10 ++++++++++ app/code/Magento/Sales/Model/Download.php | 7 +++++++ .../Wishlist/Controller/Index/DownloadCustomOption.php | 5 +++++ 5 files changed, 37 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php index c0d10c720f6f6..a7add0ad87b89 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidateFactory.php @@ -6,9 +6,14 @@ namespace Magento\Catalog\Model\Product\Option\Type\File; +/** + * Class ValidateFactory. Creates Validator with type "ExistingValidate" + */ class ValidateFactory { /** + * Main factory method + * * @return \Zend_Validate */ public function create() diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php index 7449c9ea78883..fef4999a1174a 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php @@ -14,6 +14,8 @@ use Magento\Framework\App\ObjectManager; /** + * Validator class. Represents logic for validation file given from product option + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ValidatorFile extends Validator @@ -70,6 +72,8 @@ class ValidatorFile extends Validator private $random; /** + * Constructor method + * * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Framework\File\Size $fileSize @@ -96,6 +100,8 @@ public function __construct( } /** + * Setter method for the product + * * @param Product $product * @return $this */ @@ -106,6 +112,8 @@ public function setProduct(Product $product) } /** + * Validation method + * * @param \Magento\Framework\DataObject $processingParams * @param \Magento\Catalog\Model\Product\Option $option * @return array @@ -253,6 +261,8 @@ protected function initFilesystem() } /** + * Validate contents length method + * * @return bool * @todo need correctly name */ diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php index 31e89d424e3b2..100ad37273cff 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorInfo.php @@ -37,6 +37,8 @@ class ValidatorInfo extends Validator protected $fileRelativePath; /** + * Construct method + * * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Framework\File\Size $fileSize @@ -56,6 +58,8 @@ public function __construct( } /** + * Setter method for property "useQuotePath" + * * @param mixed $useQuotePath * @return $this */ @@ -66,6 +70,8 @@ public function setUseQuotePath($useQuotePath) } /** + * Validate method for the option value depends on an option + * * @param array $optionValue * @param \Magento\Catalog\Model\Product\Option $option * @return bool @@ -112,6 +118,8 @@ public function validate($optionValue, $option) } /** + * Method for creation secret key for the given file + * * @param string $fileRelativePath * @return string */ @@ -121,6 +129,8 @@ protected function buildSecretKey($fileRelativePath) } /** + * Calculates path for the file + * * @param array $optionValue * @return void */ diff --git a/app/code/Magento/Sales/Model/Download.php b/app/code/Magento/Sales/Model/Download.php index 14395bb9afedd..a76b72bfa41dd 100644 --- a/app/code/Magento/Sales/Model/Download.php +++ b/app/code/Magento/Sales/Model/Download.php @@ -8,6 +8,9 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; +/** + * Class Download. Represents download logic for files + */ class Download { /** @@ -36,6 +39,8 @@ class Download protected $rootDirBasePath; /** + * Constructor method + * * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDatabase * @param \Magento\MediaStorage\Model\File\Storage\DatabaseFactory $storageDatabaseFactory @@ -84,6 +89,8 @@ public function downloadFile($info) } /** + * Method checks, if file can be returned depends on the given filepath + * * @param string $relativePath * @return bool */ diff --git a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php index 095e64ddf7620..9ffec68780aa1 100644 --- a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php +++ b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php @@ -11,6 +11,9 @@ use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Serialize\Serializer\Json; +/** + * Class DownloadCustomOption. Represents request-flow logic for option's file download + */ class DownloadCustomOption extends \Magento\Wishlist\Controller\AbstractIndex { /** @@ -26,6 +29,8 @@ class DownloadCustomOption extends \Magento\Wishlist\Controller\AbstractIndex private $json; /** + * Constructor method + * * @param Action\Context $context * @param \Magento\Framework\App\Response\Http\FileFactory $fileResponseFactory * @param Json|null $json From d2e66ba244ce394c8eaa2abd2992a9d1d8ded558 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 10 Oct 2018 12:19:58 -0500 Subject: [PATCH 242/812] MAGETWO-95588: Swatches on category page does not work - Added configuration for listing pages - Added tests --- .../AdminCreateProductAttributeSection.xml | 1 + .../Mftf/Test/AdminCreateImageSwatchTest.xml | 28 +++++++++++++++++++ .../templates/product/listing/renderer.phtml | 3 +- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml index 17778c76da9b9..b3ecf5bcedba9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateProductAttributeSection.xml @@ -72,5 +72,6 @@ <element name="Scope" type="select" selector="#is_global"/> <element name="AddToColumnOptions" type="select" selector="#is_used_in_grid"/> <element name="UseInFilterOptions" type="select" selector="#is_filterable_in_grid"/> + <element name="UseInProductListing" type="select" selector="#used_in_product_listing"/> </section> </sections> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml index a763bda2e494f..dd497cca2c2de 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml @@ -19,6 +19,7 @@ <group value="Swatches"/> </annotations> <before> + <createData entity="ApiCategory" stepKey="createCategory"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> <after> @@ -67,6 +68,11 @@ <click selector="{{AttributePropertiesSection.AdvancedProperties}}" stepKey="expandAdvancedProperties"/> <selectOption selector="{{AttributePropertiesSection.Scope}}" userInput="1" stepKey="selectGlobalScope"/> + <scrollToTopOfPage stepKey="scrollToTabs"/> + <click selector="{{StorefrontPropertiesSection.StoreFrontPropertiesTab}}" stepKey="clickStorefrontPropertiesTab"/> + <waitForElementVisible selector="{{AdvancedAttributePropertiesSection.UseInProductListing}}" stepKey="waitForTabSwitch"/> + <selectOption selector="{{AdvancedAttributePropertiesSection.UseInProductListing}}" userInput="Yes" stepKey="useInProductListing"/> + <!-- Save the new product attribute --> <click selector="{{AttributePropertiesSection.SaveAndEdit}}" stepKey="clickSaveAndEdit1"/> <waitForElementVisible selector="{{AdminProductMessagesSection.successMessage}}" stepKey="waitForSuccess"/> @@ -97,6 +103,7 @@ <actionGroup ref="fillMainProductForm" stepKey="fillProductForm"> <argument name="product" value="BaseConfigurableProduct"/> </actionGroup> + <searchAndMultiSelectOption selector="{{AdminProductFormSection.categoriesDropdown}}" parameterArray="[$$createCategory.name$$]" stepKey="fillCategory"/> <!-- Create configurations based off the Image Swatch we created earlier --> <click selector="{{AdminProductFormConfigurationsSection.createConfigurations}}" stepKey="clickCreateConfigurations"/> @@ -134,5 +141,26 @@ <expectedResult type="string">adobe-base</expectedResult> <actualResult type="string">{$grabSwatch6}</actualResult> </assertContains> + + <!-- Go to the product listing page and see text swatch options --> + <amOnPage url="$$createCategory.name$$.html" stepKey="goToCategoryPageStorefront"/> + <waitForPageLoad stepKey="waitForProductListingPage"/> + + <!-- Verify the storefront --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.nthSwatchOption('1')}}" userInput="style" stepKey="grabSwatch7"/> + <assertContains stepKey="assertSwatch7"> + <expectedResult type="string">adobe-thumb</expectedResult> + <actualResult type="string">{$grabSwatch7}</actualResult> + </assertContains> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.nthSwatchOption('2')}}" userInput="style" stepKey="grabSwatch8"/> + <assertContains stepKey="assertSwatch8"> + <expectedResult type="string">adobe-small</expectedResult> + <actualResult type="string">{$grabSwatch8}</actualResult> + </assertContains> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.nthSwatchOption('3')}}" userInput="style" stepKey="grabSwatch9"/> + <assertContains stepKey="assertSwatch9"> + <expectedResult type="string">adobe-base</expectedResult> + <actualResult type="string">{$grabSwatch9}</actualResult> + </assertContains> </test> </tests> 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 e65345b38d9b2..410d4046ae17f 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 @@ -21,7 +21,8 @@ $productId = $block->getProduct()->getId(); "numberToShow": <?= /* @escapeNotVerified */ $block->getNumberSwatchesPerProduct(); ?>, "jsonConfig": <?= /* @escapeNotVerified */ $block->getJsonConfig(); ?>, "jsonSwatchConfig": <?= /* @escapeNotVerified */ $block->getJsonSwatchConfig(); ?>, - "mediaCallback": "<?= /* @escapeNotVerified */ $block->getMediaCallback() ?>" + "mediaCallback": "<?= /* @escapeNotVerified */ $block->getMediaCallback() ?>", + "jsonSwatchImageSizeConfig": <?php /* @noEscape */ echo $block->getJsonSwatchSizeConfig() ?> } } } From 43b3cae9c610984b29c976394ca0ab292d61d0a6 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 10 Oct 2018 13:47:31 -0500 Subject: [PATCH 243/812] MAGETWO-95588: Swatches on category page does not work - Fixed static issue --- .../view/frontend/templates/product/listing/renderer.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 410d4046ae17f..c30c96fc890f7 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 @@ -22,7 +22,7 @@ $productId = $block->getProduct()->getId(); "jsonConfig": <?= /* @escapeNotVerified */ $block->getJsonConfig(); ?>, "jsonSwatchConfig": <?= /* @escapeNotVerified */ $block->getJsonSwatchConfig(); ?>, "mediaCallback": "<?= /* @escapeNotVerified */ $block->getMediaCallback() ?>", - "jsonSwatchImageSizeConfig": <?php /* @noEscape */ echo $block->getJsonSwatchSizeConfig() ?> + "jsonSwatchImageSizeConfig": <?= /* @noEscape */ $block->getJsonSwatchSizeConfig() ?> } } } From 4c9166f6bbce8949e8ce57b56b2a232134fe3c64 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Wed, 10 Oct 2018 14:52:44 -0500 Subject: [PATCH 244/812] MC-4323: Cannot Add Slider WYSIWYG Image From Gallery or Link to Image in Gallery After Page Has Been Saved - Fixed editor callback to use the global editor --- lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js index 760e0785a7893..bd47391e2ed2e 100644 --- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js +++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js @@ -117,7 +117,7 @@ define([ jQuery.when.apply(jQuery, deferreds).done(function () { tinyMCE4.init(settings); this.getPluginButtons().hide(); - this.eventBus.attachEventHandler('open_browser_callback', this.openFileBrowser); + this.eventBus.attachEventHandler('open_browser_callback', tinyMceEditors.get(self.id).openFileBrowser); }.bind(this)); }, From 8cbe1263925df0ac91091f3921f349dcf27efa3c Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 10 Oct 2018 16:48:53 -0500 Subject: [PATCH 245/812] MAGETWO-71675: Customer can't see available Payment Method for specific country --- .../Mftf/ActionGroup/CheckoutActionGroup.xml | 22 +++++++ .../Test/StorefrontCustomerCheckoutTest.xml | 65 +++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index eef35abcc978a..41b1e0d811851 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -104,6 +104,28 @@ <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> </actionGroup> + <!-- Logged in user checkout filling shipping section --> + <actionGroup name="LoggedInUserCheckoutAddNewShippingSectionWithoutRegionActionGroup"> + <arguments> + <argument name="customerVar"/> + <argument name="customerAddressVar"/> + </arguments> + <fillField selector="{{CheckoutShippingSection.firstName}}" userInput="{{customerVar.firstname}}" stepKey="enterFirstName"/> + <fillField selector="{{CheckoutShippingSection.lastName}}" userInput="{{customerVar.lastname}}" stepKey="enterLastName"/> + <fillField selector="{{CheckoutShippingSection.street}}" userInput="{{customerAddressVar.street[0]}}" stepKey="enterStreet"/> + <fillField selector="{{CheckoutShippingSection.city}}" userInput="{{customerAddressVar.city}}" stepKey="enterCity"/> + <fillField selector="{{CheckoutShippingSection.postcode}}" userInput="{{customerAddressVar.postcode}}" stepKey="enterPostcode"/> + <selectOption selector="{{CheckoutShippingSection.country}}" userInput="{{customerAddressVar.country_id}}" stepKey="enterCountry"/> + <fillField selector="{{CheckoutShippingSection.telephone}}" userInput="{{customerAddressVar.telephone}}" stepKey="enterTelephone"/> + <click selector="{{CheckoutShippingSection.saveAddress}}" stepKey="clickSaveAddress"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <click selector="{{CheckoutShippingSection.firstShippingMethod}}" stepKey="selectFirstShippingMethod"/> + <waitForElement selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> + <waitForElement selector="{{CheckoutPaymentSection.paymentSectionTitle}}" time="30" stepKey="waitForPaymentSectionLoaded"/> + <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> + </actionGroup> + <!-- Check product in checkout cart items --> <actionGroup name="CheckProductInCheckoutCartItemsActionGroup"> <arguments> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml index 6ea8d8a167294..2034c99fb4ae9 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml @@ -193,4 +193,69 @@ <waitForPageLoad stepKey="waitForOrderSuccessPage2"/> <see stepKey="seeSuccessMessage2" selector="{{CheckoutSuccessMainSection.success}}" userInput="Your order number is:" /> </test> + <test name="StorefrontCustomerCheckoutTestWithRestrictedCountriesForPayment"> + <annotations> + <features value="Checkout"/> + <stories value="Checkout flow if payment solutions are not available"/> + <title value="Checkout via Customer Checkout with restricted countries for payment"/> + <description value="Should be able to place an order as a Customer with restricted countries for payment."/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-42653"/> + <group value="checkout"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="ApiSimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <magentoCLI stepKey="allowSpecificValue" command="config:set payment/checkmo/allowspecific 1" /> + <magentoCLI stepKey="specificCountryValue" command="config:set payment/checkmo/specificcountry GB" /> + <createData entity="Simple_US_Customer" stepKey="simpleuscustomer"/> + </before> + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <magentoCLI stepKey="allowSpecificValue" command="config:set payment/checkmo/allowspecific 0" /> + <magentoCLI stepKey="specificCountryValue" command="config:set payment/checkmo/specificcountry ''" /> + </after> + <!-- Login as Customer --> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="customerLogin"> + <argument name="Customer" value="$$simpleuscustomer$$" /> + </actionGroup> + + <!-- Add product to cart --> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> + <click selector="{{StorefrontCategoryMainSection.AddToCartBtn}}" stepKey="addToCart"/> + <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> + <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> + <see selector="{{StorefrontMinicartSection.quantity}}" userInput="1" stepKey="seeCartQuantity"/> + + <!-- Go to checkout page --> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="customerGoToCheckoutFromMinicart" /> + + <!-- Select address --> + <click stepKey="selectAddress" selector="{{CheckoutShippingMethodsSection.firstShippingMethod}}"/> + <waitForElement stepKey="waitNextButton" selector="{{CheckoutShippingMethodsSection.next}}" time="30"/> + <click stepKey="clickNextButton" selector="{{CheckoutShippingMethodsSection.next}}" /> + <waitForPageLoad stepKey="waitBillingForm"/> + <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> + <waitForElementVisible selector="{{CheckoutPaymentSection.noQuotes}}" stepKey="waitMessage"/> + <see userInput="No Payment method available." stepKey="checkMessage"/> + + <!-- Fill UK Address and verify that payment available and checkout successful --> + <click selector="{{CheckoutHeaderSection.shippingMethodStep}}" stepKey="goToShipping" /> + <click selector="{{CheckoutShippingSection.newAddressButton}}" stepKey="fillNewAddress" /> + <actionGroup ref="LoggedInUserCheckoutAddNewShippingSectionWithoutRegionActionGroup" stepKey="customerCheckoutFillingShippingSectionUK"> + <argument name="customerVar" value="CustomerEntityOne" /> + <argument name="customerAddressVar" value="UK_Not_Default_Address" /> + </actionGroup> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="customerSelectCheckMoneyOrderPayment" /> + <actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="customerPlaceorder"> + <argument name="orderNumberMessage" value="CONST.successCheckoutOrderNumberMessage" /> + <argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage" /> + </actionGroup> + </test> </tests> From 913f88a8a35e2f76339cef8648fdd5e2a7c826f9 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Wed, 10 Oct 2018 17:09:01 -0500 Subject: [PATCH 246/812] MAGETWO-95238: Cannot reset customer password from Admin Panel - added functional test to cover the bug fix --- .../AdminCustomerMainActionsSection.xml | 1 + .../Test/AdminResetCustomerPasswordTest.xml | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerMainActionsSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerMainActionsSection.xml index 37ea99d652fb9..3ff880c64e6d6 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerMainActionsSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerMainActionsSection.xml @@ -10,5 +10,6 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminCustomerMainActionsSection"> <element name="saveButton" type="button" selector="#save" timeout="30"/> + <element name="resetPassword" type="button" selector="#resetPassword" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml new file mode 100644 index 0000000000000..cff605d7c907f --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml @@ -0,0 +1,37 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminResetCustomerPasswordTest"> + <annotations> + <features value="Customer"/> + <stories value="Admin should be able to reset an existing customer's password"/> + <description value="Admin should be able to reset customer password"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-30875"/> + <group value="customer"/> + </annotations> + <before> + <createData entity="Simple_US_Customer" stepKey="customer"/> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + </before> + <after> + <deleteData createDataKey="customer" stepKey="deleteCustomer"/> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + <!--Edit customer info--> + <actionGroup ref="OpenEditCustomerFromAdminActionGroup" stepKey="OpenEditCustomerFrom"> + <argument name="customer" value="$$customer$$"/> + </actionGroup> + <click selector="{{AdminCustomerMainActionsSection.resetPassword}}" stepKey="resetPassword"/> + <see userInput="The customer will receive an email with a link to reset password." stepKey="messageThatLinkToPasswordResetIsSent"/> + </test> +</tests> + + From 848a7c2c209d54bde25e664682b42e4a46e90bd3 Mon Sep 17 00:00:00 2001 From: duhon <duhon@rambler.ru> Date: Wed, 10 Oct 2018 19:54:29 +0300 Subject: [PATCH 247/812] MAGETWO-95652: Call to \Magento\Framework\Api\MetadataServiceInterface::getCustomAttributesMetadata leads to fatal error --- app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php b/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php index b83bb97301b9c..1ac7675b10289 100644 --- a/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php +++ b/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php @@ -32,6 +32,6 @@ public function __construct(array $blackList = []) */ public function execute(array $attributes): array { - return array_diff($attributes, $this->blackList); + return array_diff_key($attributes, array_flip($this->blackList)); } } From 41cb4685fc24b296de837ddf8c39ab377e7347a9 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Thu, 11 Oct 2018 10:24:11 +0300 Subject: [PATCH 248/812] MAGETWO-91563: Gift wrapping selection does not display in shopping cart - Add GET interface --- app/code/Magento/Checkout/Controller/Cart/UpdatePost.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php index 9f0dcc6d9c18f..b49635a951e39 100644 --- a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php +++ b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php @@ -8,8 +8,9 @@ use Magento\Checkout\Model\Cart\RequestQuantityProcessor; use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\App\Action\HttpGetActionInterface; -class UpdatePost extends \Magento\Checkout\Controller\Cart implements HttpPostActionInterface +class UpdatePost extends \Magento\Checkout\Controller\Cart implements HttpGetActionInterface, HttpPostActionInterface { /** * @var RequestQuantityProcessor From e210b7044a7bfd503082249a72a95a6c0ae03eb5 Mon Sep 17 00:00:00 2001 From: Joseph Maxwell <joseph@swiftotter.com> Date: Wed, 6 Jun 2018 10:40:48 -0500 Subject: [PATCH 249/812] Bundle checkboxes now are checked when item edited from cart --- .../Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php index 5d326e7c01d19..ed6a4d1ad7209 100644 --- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php +++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php @@ -167,7 +167,9 @@ protected function _getSelectedOptions() */ protected function assignSelection(\Magento\Bundle\Model\Option $option, $selectionId) { - if ($selectionId && $option->getSelectionById($selectionId)) { + if (is_array($selectionId)) { + $this->_selectedOptions = $selectionId; + } else if ($selectionId && $option->getSelectionById($selectionId)) { $this->_selectedOptions = $selectionId; } elseif (!$option->getRequired()) { $this->_selectedOptions = 'None'; From 53f59424c0b049e2f275c50bbced1fc9b42a6916 Mon Sep 17 00:00:00 2001 From: Joseph Maxwell <joseph@swiftotter.com> Date: Wed, 6 Jun 2018 10:44:38 -0500 Subject: [PATCH 250/812] #4942: bundled products now retain customer selections when editing from cart --- .../Block/Catalog/Product/View/Type/Bundle.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php index 62a2fa1c47e1e..cab923da49215 100644 --- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php +++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php @@ -193,6 +193,18 @@ public function getJsonConfig() $options[$optionId]['selections'][$configValue]['qty'] = $configQty; } } + + + $preConfiguredQtys = $preConfiguredValues->getData("bundle_option_qty/${optionId}") ?? []; + $selections = $options[$optionId]['selections']; + array_walk($selections, function(&$selection, $selectionId) use ($preConfiguredQtys) { + if (is_array($preConfiguredQtys) && isset($preConfiguredQtys[$selectionId])) { + $selection['qty'] = $preConfiguredQtys[$selectionId]; + } else if ((int)$preConfiguredQtys > 0) { + $selection['qty'] = $preConfiguredQtys; + } + }); + $options[$optionId]['selections'] = $selections; } $position++; } From 8050d5014037c9ae845be1fd1338b4f4ce7b8d19 Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Tue, 18 Sep 2018 09:05:00 +0000 Subject: [PATCH 251/812] magento/magento2#4942: fix code styles in the app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php file --- .../Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php index cab923da49215..1cd0c41abb528 100644 --- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php +++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php @@ -194,10 +194,9 @@ public function getJsonConfig() } } - $preConfiguredQtys = $preConfiguredValues->getData("bundle_option_qty/${optionId}") ?? []; $selections = $options[$optionId]['selections']; - array_walk($selections, function(&$selection, $selectionId) use ($preConfiguredQtys) { + array_walk($selections, function (&$selection, $selectionId) use ($preConfiguredQtys) { if (is_array($preConfiguredQtys) && isset($preConfiguredQtys[$selectionId])) { $selection['qty'] = $preConfiguredQtys[$selectionId]; } else if ((int)$preConfiguredQtys > 0) { From 0bd75c823e506e8099cfa4dbb5877be5662bcebb Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Thu, 4 Oct 2018 16:16:01 +0300 Subject: [PATCH 252/812] =?UTF-8?q?NGCOM-2997:=20#4942=20and=20bundle=20ch?= =?UTF-8?q?eckbox=20bug=20#15905.=20Fix=20functional=20and=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Catalog/Product/View/Type/Bundle.php | 43 +++++++++++++------ .../Test/StorefrontEditBundleProductTest.xml | 5 +-- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php index 1cd0c41abb528..fa488b073f515 100644 --- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php +++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php @@ -7,6 +7,7 @@ use Magento\Bundle\Model\Option; use Magento\Catalog\Model\Product; +use Magento\Framework\DataObject; /** * Catalog bundle product info block @@ -170,7 +171,7 @@ public function getJsonConfig() $defaultValues = []; $preConfiguredFlag = $currentProduct->hasPreconfiguredValues(); - /** @var \Magento\Framework\DataObject|null $preConfiguredValues */ + /** @var DataObject|null $preConfiguredValues */ $preConfiguredValues = $preConfiguredFlag ? $currentProduct->getPreconfiguredValues() : null; $position = 0; @@ -193,23 +194,13 @@ public function getJsonConfig() $options[$optionId]['selections'][$configValue]['qty'] = $configQty; } } - - $preConfiguredQtys = $preConfiguredValues->getData("bundle_option_qty/${optionId}") ?? []; - $selections = $options[$optionId]['selections']; - array_walk($selections, function (&$selection, $selectionId) use ($preConfiguredQtys) { - if (is_array($preConfiguredQtys) && isset($preConfiguredQtys[$selectionId])) { - $selection['qty'] = $preConfiguredQtys[$selectionId]; - } else if ((int)$preConfiguredQtys > 0) { - $selection['qty'] = $preConfiguredQtys; - } - }); - $options[$optionId]['selections'] = $selections; + $options = $this->processOptions($optionId, $options, $preConfiguredValues); } $position++; } $config = $this->getConfigData($currentProduct, $options); - $configObj = new \Magento\Framework\DataObject( + $configObj = new DataObject( [ 'config' => $config, ] @@ -414,4 +405,30 @@ private function getConfigData(Product $product, array $options) ]; return $config; } + + /** + * Set preconfigured quantities and selections to options. + * + * @param string $optionId + * @param array $options + * @param DataObject $preConfiguredValues + * @return array + */ + private function processOptions(string $optionId, array $options, DataObject $preConfiguredValues) + { + $preConfiguredQtys = $preConfiguredValues->getData("bundle_option_qty/${optionId}") ?? []; + $selections = $options[$optionId]['selections']; + array_walk($selections, function (&$selection, $selectionId) use ($preConfiguredQtys) { + if (is_array($preConfiguredQtys) && isset($preConfiguredQtys[$selectionId])) { + $selection['qty'] = $preConfiguredQtys[$selectionId]; + } else { + if ((int)$preConfiguredQtys > 0) { + $selection['qty'] = $preConfiguredQtys; + } + } + }); + $options[$optionId]['selections'] = $selections; + + return $options; + } } diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml index f94cd83f4e7d7..4945308c26c4a 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml @@ -94,9 +94,8 @@ <click stepKey="clickEdit" selector="{{CheckoutCartProductSection.nthEditButton('1')}}"/> <waitForPageLoad stepKey="waitForStorefront2"/> - <!-- Choose both of the options on the storefront --> - <click stepKey="selectFirstBundleOption2" selector="{{StorefrontBundledSection.nthBundledOption('1','1')}}"/> - <click stepKey="selectSecondBundleOption2" selector="{{StorefrontBundledSection.nthBundledOption('1','2')}}"/> + <!-- Check second one option to choose both of the options on the storefront --> + <click selector="{{StorefrontBundledSection.bundleOption('1','2')}}" stepKey="selectSecondBundleOption2"/> <waitForPageLoad stepKey="waitForPriceUpdate3"/> <see stepKey="seeDoublePrice" selector="{{StorefrontBundledSection.configuredPrice}}" userInput="2,460.00"/> From 38b91b77bef7604d747780a3cad2d342d05453d3 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Thu, 11 Oct 2018 11:52:56 +0300 Subject: [PATCH 253/812] ENGCOM-1928: 14294 - Fixes 'back' functionality after switching a store view. #15961. Fix functional tests. --- app/code/Magento/Store/Block/Switcher.php | 20 +++++++++++++++++++ .../frontend/templates/switch/languages.phtml | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Store/Block/Switcher.php b/app/code/Magento/Store/Block/Switcher.php index f15349f11066d..e162a2a0abe16 100644 --- a/app/code/Magento/Store/Block/Switcher.php +++ b/app/code/Magento/Store/Block/Switcher.php @@ -265,4 +265,24 @@ public function getTargetStorePostData(Store $store, $data = []) $data ); } + + /** + * Returns target store redirect url. + * + * @param Store $store + * @return string + */ + public function getTargetStoreRedirectUrl(Store $store) + { + return $this->getUrl( + 'stores/store/redirect', + [ + '___store' => $store->getCode(), + '___from_store' => $this->getCurrentStoreCode(), + ActionInterface::PARAM_NAME_URL_ENCODED => $this->urlHelper->getEncodedUrl( + $store->getCurrentUrl(false) + ), + ] + ); + } } diff --git a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml index 6d041a9e22c5d..411a1ef3c9a32 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml @@ -27,7 +27,7 @@ <?php foreach ($block->getStores() as $_lang): ?> <?php if ($_lang->getId() != $block->getCurrentStoreId()): ?> <li class="view-<?= $block->escapeHtml($_lang->getCode()) ?> switcher-option"> - <a href="<?= $block->escapeUrl($_lang->getCurrentUrl(true)) ?>"> + <a href="<?= $block->escapeUrl($block->getTargetStoreRedirectUrl($_lang)) ?>"> <?= $block->escapeHtml($_lang->getName()) ?> </a> </li> From a0085a80984f0d0c26ef6d1bd93eae6bfa03731c Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Thu, 11 Oct 2018 13:58:35 +0400 Subject: [PATCH 254/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Add automated test --- ...AdminProductFormGroupedProductsSection.xml | 4 + .../AdminSortingAssociatedProductsTest.xml | 207 ++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminSortingAssociatedProductsTest.xml diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml index 64dcd9566d890..0739c4e601b62 100644 --- a/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml @@ -11,5 +11,9 @@ <section name="AdminProductFormGroupedProductsSection"> <element name="toggleGroupedProduct" type="button" selector="div[data-index=grouped] .admin__collapsible-title"/> <element name="addProductsToGroup" type="button" selector="button[data-index='grouped_products_button']" timeout="30"/> + <element name="nextActionButton" type="button" selector="//button[@class='action-next']"/> + <element name="previousActionButton" type="button" selector="//button[@class='action-previous']"/> + <element name="positionProduct" type="input" selector="//tbody/tr[{{arg}}][contains(@class,'data-row')]/td[10]//input[@class='position-widget-input']" parameterized="true"/> + <element name="nameProductFromGrid" type="text" selector="//tbody/tr[{{arg}}][contains(@class,'data-row')]/td[4]//*[@class='admin__field-control']//span" parameterized="true"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminSortingAssociatedProductsTest.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminSortingAssociatedProductsTest.xml new file mode 100644 index 0000000000000..ad5fbbb30edeb --- /dev/null +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminSortingAssociatedProductsTest.xml @@ -0,0 +1,207 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminSortingAssociatedProductsTest"> + <annotations> + <features value="GroupedProduct"/> + <stories value="MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages"/> + <title value="Grouped Products: Sorting Associated Products Between Pages"/> + <description value="Make sure that products in grid were recalculated when sorting associated products between pages"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-95085"/> + <group value="GroupedProduct"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + <createData entity="_defaultCategory" stepKey="category"/> + <!-- Create 23 products so that grid can have more than one page --> + <createData entity="ApiSimpleProduct" stepKey="product1"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product2"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product3"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product4"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product5"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product6"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product7"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product8"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product9"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product10"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product11"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product12"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product13"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product14"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product15"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product16"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product17"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product18"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product19"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product20"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product21"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product22"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="product23"> + <requiredEntity createDataKey="category"/> + </createData> + </before> + <after> + <!--Delete created grouped product--> + <actionGroup ref="deleteProductUsingProductGrid" stepKey="deleteProduct"> + <argument name="product" value="GroupedProduct"/> + </actionGroup> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" + dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFilters"/> + <deleteData createDataKey="product1" stepKey="deleteProduct1"/> + <deleteData createDataKey="product2" stepKey="deleteProduct2"/> + <deleteData createDataKey="product3" stepKey="deleteProduct3"/> + <deleteData createDataKey="product4" stepKey="deleteProduct4"/> + <deleteData createDataKey="product5" stepKey="deleteProduct5"/> + <deleteData createDataKey="product6" stepKey="deleteProduct6"/> + <deleteData createDataKey="product7" stepKey="deleteProduct7"/> + <deleteData createDataKey="product8" stepKey="deleteProduct8"/> + <deleteData createDataKey="product9" stepKey="deleteProduct9"/> + <deleteData createDataKey="product10" stepKey="deleteProduct10"/> + <deleteData createDataKey="product11" stepKey="deleteProduct11"/> + <deleteData createDataKey="product12" stepKey="deleteProduct12"/> + <deleteData createDataKey="product13" stepKey="deleteProduct13"/> + <deleteData createDataKey="product14" stepKey="deleteProduct14"/> + <deleteData createDataKey="product15" stepKey="deleteProduct15"/> + <deleteData createDataKey="product16" stepKey="deleteProduct16"/> + <deleteData createDataKey="product17" stepKey="deleteProduct17"/> + <deleteData createDataKey="product18" stepKey="deleteProduct18"/> + <deleteData createDataKey="product19" stepKey="deleteProduct19"/> + <deleteData createDataKey="product20" stepKey="deleteProduct20"/> + <deleteData createDataKey="product21" stepKey="deleteProduct21"/> + <deleteData createDataKey="product22" stepKey="deleteProduct22"/> + <deleteData createDataKey="product23" stepKey="deleteProduct23"/> + <deleteData createDataKey="category" stepKey="deleteCategory"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <!--Create grouped Product--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> + <waitForPageLoad stepKey="waitForProductIndexPage"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetProductGridColumnsInitial"/> + <actionGroup ref="goToCreateProductPage" stepKey="goToCreateProduct"> + <argument name="product" value="GroupedProduct"/> + </actionGroup> + <actionGroup ref="fillGroupedProductForm" stepKey="fillProductForm"> + <argument name="product" value="GroupedProduct"/> + </actionGroup> + + <scrollTo selector="{{AdminProductFormGroupedProductsSection.toggleGroupedProduct}}" x="0" y="-100" stepKey="scrollToGroupedSection"/> + <conditionalClick selector="{{AdminProductFormGroupedProductsSection.toggleGroupedProduct}}" dependentSelector="{{AdminProductFormGroupedProductsSection.addProductsToGroup}}" visible="false" stepKey="openGroupedProductsSection"/> + <click selector="body" stepKey="clickBodyToCorrectFocusGrouped"/> + <click selector="{{AdminProductFormGroupedProductsSection.addProductsToGroup}}" stepKey="clickAddProductsToGroup"/> + <waitForElementVisible selector="{{AdminAddProductsToGroupPanel.filters}}" stepKey="waitForGroupedProductModal"/> + <actionGroup ref="filterProductGridBySku2" stepKey="filterGroupedProducts"> + <argument name="sku" value="api-simple-product"/> + </actionGroup> + + <!-- Select all, then start the bulk update attributes flow --> + <click selector="{{AdminProductGridSection.multicheckDropdown}}" stepKey="openMulticheckDropdown"/> + <click selector="{{AdminProductGridSection.multicheckOption('Select All')}}" stepKey="selectAllProductInFilteredGrid"/> + + <click selector="{{AdminAddProductsToGroupPanel.addSelectedProducts}}" stepKey="clickAddSelectedGroupProducts"/> + <waitForPageLoad stepKey="waitForProductsAdded"/> + + <actionGroup ref="saveProductForm" stepKey="saveProduct"/> + + <!--Open created Product group--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex"/> + <waitForPageLoad stepKey="waitForProductIndexPageLoad"/> + <actionGroup ref="resetProductGridToDefaultView" stepKey="resetFiltersIfExist"/> + <actionGroup ref="searchProductGridByKeyword" stepKey="searchProductGridForm"> + <argument name="keyword" value="GroupedProduct.name"/> + </actionGroup> + <click selector="{{AdminProductGridSection.selectRowBasedOnName(GroupedProduct.name)}}" stepKey="openGroupedProduct"/> + <waitForPageLoad stepKey="waitForProductEditPageLoad"/> + + <scrollTo selector="{{AdminProductFormGroupedProductsSection.toggleGroupedProduct}}" x="0" y="-100" stepKey="scrollToGroupedSection2"/> + <conditionalClick selector="{{AdminProductFormGroupedProductsSection.toggleGroupedProduct}}" dependentSelector="{{AdminProductFormGroupedProductsSection.addProductsToGroup}}" visible="false" stepKey="openGroupedProductsSection2"/> + + <!--Change position value for the Product Position 0--> + <grabTextFrom selector="{{AdminProductFormGroupedProductsSection.nameProductFromGrid('1')}}" stepKey="grabNameProductPosition0"/> + <grabTextFrom selector="{{AdminProductFormGroupedProductsSection.nameProductFromGrid('2')}}" stepKey="grabNameProductPositionFirst"/> + <fillField selector="{{AdminProductFormGroupedProductsSection.positionProduct('1')}}" userInput="21" stepKey="fillFieldProductPosition0"/> + <doubleClick selector="{{AdminProductFormGroupedProductsSection.nextActionButton}}" stepKey="clickButton"/> + <waitForAjaxLoad stepKey="waitForAjax1"/> + + <!--Go to next page and verify that Products in grid were recalculated--> + <doubleClick selector="{{AdminProductFormGroupedProductsSection.nextActionButton}}" stepKey="clickNextActionButton"/> + <waitForAjaxLoad stepKey="waitForAjax2"/> + + <grabTextFrom selector="{{AdminProductFormGroupedProductsSection.nameProductFromGrid('2')}}" stepKey="grabNameProductPosition21"/> + <assertEquals stepKey="assertProductsRecalculated"> + <actualResult type="string">$grabNameProductPosition0</actualResult> + <expectedResult type="string">$grabNameProductPosition21</expectedResult> + </assertEquals> + + <!--Change position value for the product to 1--> + <fillField selector="{{AdminProductFormGroupedProductsSection.positionProduct('2')}}" userInput="1" stepKey="fillFieldProductPosition1"/> + <doubleClick selector="{{AdminProductFormGroupedProductsSection.previousActionButton}}" stepKey="clickButton2"/> + <waitForAjaxLoad stepKey="waitForAjax3"/> + + <!--Go to previous page and verify that Products in grid were recalculated--> + <click selector="{{AdminProductFormGroupedProductsSection.previousActionButton}}" stepKey="clickPreviousActionButton"/> + <waitForAjaxLoad stepKey="waitForAjax4"/> + <grabTextFrom selector="{{AdminProductFormGroupedProductsSection.nameProductFromGrid('2')}}" stepKey="grabNameProductPosition2"/> + <grabTextFrom selector="{{AdminProductFormGroupedProductsSection.nameProductFromGrid('1')}}" stepKey="grabNameProductPositionZero"/> + <assertEquals stepKey="assertProductsRecalculated2"> + <actualResult type="string">$grabNameProductPosition2</actualResult> + <expectedResult type="string">$grabNameProductPosition0</expectedResult> + </assertEquals> + <assertEquals stepKey="assertProductsRecalculated3"> + <actualResult type="string">$grabNameProductPositionFirst</actualResult> + <expectedResult type="string">$grabNameProductPositionZero</expectedResult> + </assertEquals> + </test> +</tests> From d96db6d0cd9bdab0402ac44f024169197cd8cf86 Mon Sep 17 00:00:00 2001 From: duhon <duhon@rambler.ru> Date: Thu, 11 Oct 2018 14:13:51 +0300 Subject: [PATCH 255/812] MAGETWO-95652: Call to \Magento\Framework\Api\MetadataServiceInterface::getCustomAttributesMetadata leads to fatal error --- app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php b/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php index 1ac7675b10289..830b974e5edb2 100644 --- a/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php +++ b/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php @@ -27,6 +27,7 @@ public function __construct(array $blackList = []) /** * Delete custom attribute + * * @param array $attributes * @return array */ From f03ed7a2e6292f58cc5859422d660e85ec9d5cdb Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 11 Oct 2018 15:00:48 +0300 Subject: [PATCH 256/812] MAGETWO-91563: Gift wrapping selection does not display in shopping cart - Fix static test --- app/code/Magento/Checkout/Controller/Cart/UpdatePost.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php index b49635a951e39..bfc408d920ad3 100644 --- a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php +++ b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -10,6 +9,9 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\App\Action\HttpGetActionInterface; +/** + * Post update shopping cart. + */ class UpdatePost extends \Magento\Checkout\Controller\Cart implements HttpGetActionInterface, HttpPostActionInterface { /** From d3a62b1c8bcdad89d564b0a41f53a08cc81a4fa0 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 11 Oct 2018 15:32:13 +0300 Subject: [PATCH 257/812] MAGETWO-91640: Scheduled Import of Products fails on error when errors should be skipped - Fix integration test --- .../integration/testsuite/Magento/Catalog/_files/categories.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php index 9a1a6f24dffc8..a903274793c34 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php @@ -84,7 +84,7 @@ $category = $objectManager->create(\Magento\Catalog\Model\Category::class); $category->isObjectNew(true); $category->setId(6) - ->setName('Category 2.1') + ->setName('Category 2') ->setParentId(2) ->setPath('1/2/6') ->setLevel(2) From 13d360dbac2562b401a9426cf8b982062aab693c Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Thu, 11 Oct 2018 08:12:23 -0500 Subject: [PATCH 258/812] MAGETWO-95280: Storefront Images Don't Scale Back To Original Size In Mobile - revert jquery mobile upgrade --- lib/web/jquery/jquery.mobile.custom.js | 1853 +++++++++++------------- 1 file changed, 828 insertions(+), 1025 deletions(-) diff --git a/lib/web/jquery/jquery.mobile.custom.js b/lib/web/jquery/jquery.mobile.custom.js index 3b02f5346484c..f289b97b91d83 100644 --- a/lib/web/jquery/jquery.mobile.custom.js +++ b/lib/web/jquery/jquery.mobile.custom.js @@ -1,141 +1,25 @@ /* -* jQuery Mobile v1.5.0-alpha.1 +* jQuery Mobile v1.4.3 * http://jquerymobile.com * -* Copyright jQuery Foundation, Inc. and other contributors +* Copyright 2010, 2014 jQuery Foundation, Inc. and other contributors * Released under the MIT license. * http://jquery.org/license * */ (function ( root, doc, factory ) { - if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery" ], function ( $ ) { - factory( $, root, doc ); - return $.mobile; - }); - } else { - // Browser globals - factory( root.jQuery, root, doc ); - } -}( this, document, function ( jQuery, window, document, undefined ) {/*! - * jQuery Mobile Scroll Events @VERSION - * http://jquerymobile.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Scroll -//>>group: Events -//>>description: Scroll events including: scrollstart, scrollstop - - ( function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( 'events/scroll',[ "jquery" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } - } )( function( $ ) { - - var scrollEvent = "touchmove scroll"; - -// setup new event shortcuts - $.each( [ "scrollstart", "scrollstop" ], function( i, name ) { - - $.fn[ name ] = function( fn ) { - return fn ? this.bind( name, fn ) : this.trigger( name ); - }; - - // jQuery < 1.8 - if ( $.attrFn ) { - $.attrFn[ name ] = true; - } - } ); - -// also handles scrollstop - $.event.special.scrollstart = { - - enabled: true, - setup: function() { - - var thisObject = this, - $this = $( thisObject ), - scrolling, - timer; - - function trigger( event, state ) { - var originalEventType = event.type; - - scrolling = state; - - event.type = scrolling ? "scrollstart" : "scrollstop"; - $.event.dispatch.call( thisObject, event ); - event.type = originalEventType; - } - - var scrollStartHandler = $.event.special.scrollstart.handler = function ( event ) { - - if ( !$.event.special.scrollstart.enabled ) { - return; - } - - if ( !scrolling ) { - trigger( event, true ); - } - - clearTimeout( timer ); - timer = setTimeout( function() { - trigger( event, false ); - }, 50 ); - }; - - // iPhone triggers scroll after a small delay; use touchmove instead - $this.on( scrollEvent, scrollStartHandler ); - }, - teardown: function() { - $( this ).off( scrollEvent, $.event.special.scrollstart.handler ); - } - }; - - $.each( { - scrollstop: "scrollstart" - }, function( event, sourceEvent ) { - - $.event.special[ event ] = { - setup: function() { - $( this ).bind( sourceEvent, $.noop ); - }, - teardown: function() { - $( this ).unbind( sourceEvent ); - } - }; - } ); - - return $.event.special; - } ); - - /*! - * jQuery Mobile Virtual Mouse @VERSION - * http://jquerymobile.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Virtual Mouse (vmouse) Bindings -//>>group: Core -//>>description: Normalizes touch/mouse events. -//>>docs: http://api.jquerymobile.com/?s=vmouse - -// This plugin is an experiment for abstracting away the touch and mouse + if ( typeof define === "function" && define.amd ) { + // AMD. Register as an anonymous module. + define( [ "jquery" ], function ( $ ) { + factory( $, root, doc ); + return $.mobile; + }); + } else { + // Browser globals + factory( root.jQuery, root, doc ); + } +}( this, document, function ( jQuery, window, document, undefined ) {// This plugin is an experiment for abstracting away the touch and mouse // events so that developers don't have to worry about which method of input // the device their document is loaded on supports. // @@ -150,912 +34,831 @@ // The current version exposes the following virtual events to jQuery bind methods: // "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel" - ( function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( 'vmouse',[ "jquery" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } - } )( function( $ ) { - - var dataPropertyName = "virtualMouseBindings", - touchTargetPropertyName = "virtualTouchID", - touchEventProps = "clientX clientY pageX pageY screenX screenY".split( " " ), - virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split( " " ), - generalProps = ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + - "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), - mouseHookProps = $.event.mouseHooks ? $.event.mouseHooks.props : [], - mouseEventProps = generalProps.concat( mouseHookProps ), - activeDocHandlers = {}, - resetTimerID = 0, - startX = 0, - startY = 0, - didScroll = false, - clickBlockList = [], - blockMouseTriggers = false, - blockTouchTriggers = false, - eventCaptureSupported = "addEventListener" in document, - $document = $( document ), - nextTouchID = 1, - lastTouchID = 0, threshold, - i; - - $.vmouse = { - moveDistanceThreshold: 10, - clickDistanceThreshold: 10, - resetTimerDuration: 1500, - maximumTimeBetweenTouches: 100 - }; - - function getNativeEvent( event ) { - - while ( event && typeof event.originalEvent !== "undefined" ) { - event = event.originalEvent; - } - return event; - } - - function createVirtualEvent( event, eventType ) { - - var t = event.type, - oe, props, ne, prop, ct, touch, i, j, len; - - event = $.Event( event ); - event.type = eventType; - - oe = event.originalEvent; - props = generalProps; - - // addresses separation of $.event.props in to $.event.mouseHook.props and Issue 3280 - // https://github.com/jquery/jquery-mobile/issues/3280 - if ( t.search( /^(mouse|click)/ ) > -1 ) { - props = mouseEventProps; - } - - // copy original event properties over to the new event - // this would happen if we could call $.event.fix instead of $.Event - // but we don't have a way to force an event to be fixed multiple times - if ( oe ) { - for ( i = props.length; i; ) { - prop = props[ --i ]; - event[ prop ] = oe[ prop ]; - } - } - - // make sure that if the mouse and click virtual events are generated - // without a .which one is defined - if ( t.search( /mouse(down|up)|click/ ) > -1 && !event.which ) { - event.which = 1; - } - - if ( t.search( /^touch/ ) !== -1 ) { - ne = getNativeEvent( oe ); - t = ne.touches; - ct = ne.changedTouches; - touch = ( t && t.length ) ? t[ 0 ] : ( ( ct && ct.length ) ? ct[ 0 ] : undefined ); - - if ( touch ) { - for ( j = 0, len = touchEventProps.length; j < len; j++ ) { - prop = touchEventProps[ j ]; - event[ prop ] = touch[ prop ]; - } - } - } - - return event; - } - - function getVirtualBindingFlags( element ) { - - var flags = {}, - b, k; - - while ( element ) { - - b = $.data( element, dataPropertyName ); - - for ( k in b ) { - if ( b[ k ] ) { - flags[ k ] = flags.hasVirtualBinding = true; - } - } - element = element.parentNode; - } - return flags; - } - - function getClosestElementWithVirtualBinding( element, eventType ) { - var b; - while ( element ) { - - b = $.data( element, dataPropertyName ); - - if ( b && ( !eventType || b[ eventType ] ) ) { - return element; - } - element = element.parentNode; - } - return null; - } - - function enableTouchBindings() { - blockTouchTriggers = false; - } - - function disableTouchBindings() { - blockTouchTriggers = true; - } - - function enableMouseBindings() { - lastTouchID = 0; - clickBlockList.length = 0; - blockMouseTriggers = false; - - // When mouse bindings are enabled, our - // touch bindings are disabled. - disableTouchBindings(); - } - - function disableMouseBindings() { - // When mouse bindings are disabled, our - // touch bindings are enabled. - enableTouchBindings(); - } - - function clearResetTimer() { - if ( resetTimerID ) { - clearTimeout( resetTimerID ); - resetTimerID = 0; - } - } - - function startResetTimer() { - clearResetTimer(); - resetTimerID = setTimeout( function() { - resetTimerID = 0; - enableMouseBindings(); - }, $.vmouse.resetTimerDuration ); - } - - function triggerVirtualEvent( eventType, event, flags ) { - var ve; - - if ( ( flags && flags[ eventType ] ) || - ( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) { - - ve = createVirtualEvent( event, eventType ); - - $( event.target ).trigger( ve ); - } - - return ve; - } - - function mouseEventCallback( event ) { - var touchID = $.data( event.target, touchTargetPropertyName ), - ve; - - // It is unexpected if a click event is received before a touchend - // or touchmove event, however this is a known behavior in Mobile - // Safari when Mobile VoiceOver (as of iOS 8) is enabled and the user - // double taps to activate a link element. In these cases if a touch - // event is not received within the maximum time between touches, - // re-enable mouse bindings and call the mouse event handler again. - if ( event.type === "click" && $.data( event.target, "lastTouchType" ) === "touchstart" ) { - setTimeout( function() { - if ( $.data( event.target, "lastTouchType" ) === "touchstart" ) { - enableMouseBindings(); - delete $.data( event.target ).lastTouchType; - mouseEventCallback( event ); - } - }, $.vmouse.maximumTimeBetweenTouches ); - } - - if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ) { - ve = triggerVirtualEvent( "v" + event.type, event ); - if ( ve ) { - if ( ve.isDefaultPrevented() ) { - event.preventDefault(); - } - if ( ve.isPropagationStopped() ) { - event.stopPropagation(); - } - if ( ve.isImmediatePropagationStopped() ) { - event.stopImmediatePropagation(); - } - } - } - } - - function handleTouchStart( event ) { - - var touches = getNativeEvent( event ).touches, - target, flags, t; - - if ( touches && touches.length === 1 ) { - - target = event.target; - flags = getVirtualBindingFlags( target ); - - $.data( event.target, "lastTouchType", event.type ); - - if ( flags.hasVirtualBinding ) { - - lastTouchID = nextTouchID++; - $.data( target, touchTargetPropertyName, lastTouchID ); - - clearResetTimer(); - - disableMouseBindings(); - didScroll = false; - - t = getNativeEvent( event ).touches[ 0 ]; - startX = t.pageX; - startY = t.pageY; - - triggerVirtualEvent( "vmouseover", event, flags ); - triggerVirtualEvent( "vmousedown", event, flags ); - } - } - } - - function handleScroll( event ) { - if ( blockTouchTriggers ) { - return; - } - - if ( !didScroll ) { - triggerVirtualEvent( "vmousecancel", event, getVirtualBindingFlags( event.target ) ); - } - - $.data( event.target, "lastTouchType", event.type ); - - didScroll = true; - startResetTimer(); - } - - function handleTouchMove( event ) { - if ( blockTouchTriggers ) { - return; - } - - var t = getNativeEvent( event ).touches[ 0 ], - didCancel = didScroll, - moveThreshold = $.vmouse.moveDistanceThreshold, - flags = getVirtualBindingFlags( event.target ); - - $.data( event.target, "lastTouchType", event.type ); - - didScroll = didScroll || - ( Math.abs( t.pageX - startX ) > moveThreshold || - Math.abs( t.pageY - startY ) > moveThreshold ); - - if ( didScroll && !didCancel ) { - triggerVirtualEvent( "vmousecancel", event, flags ); - } - - triggerVirtualEvent( "vmousemove", event, flags ); - startResetTimer(); - } - - function handleTouchEnd( event ) { - if ( blockTouchTriggers || $.data( event.target, "lastTouchType" ) === undefined ) { - return; - } - - disableTouchBindings(); - delete $.data( event.target ).lastTouchType; - - var flags = getVirtualBindingFlags( event.target ), - ve, t; - triggerVirtualEvent( "vmouseup", event, flags ); - - if ( !didScroll ) { - ve = triggerVirtualEvent( "vclick", event, flags ); - if ( ve && ve.isDefaultPrevented() ) { - // The target of the mouse events that follow the touchend - // event don't necessarily match the target used during the - // touch. This means we need to rely on coordinates for blocking - // any click that is generated. - t = getNativeEvent( event ).changedTouches[ 0 ]; - clickBlockList.push( { - touchID: lastTouchID, - x: t.clientX, - y: t.clientY - } ); - - // Prevent any mouse events that follow from triggering - // virtual event notifications. - blockMouseTriggers = true; - } - } - triggerVirtualEvent( "vmouseout", event, flags ); - didScroll = false; - - startResetTimer(); - } - - function hasVirtualBindings( ele ) { - var bindings = $.data( ele, dataPropertyName ), - k; - - if ( bindings ) { - for ( k in bindings ) { - if ( bindings[ k ] ) { - return true; - } - } - } - return false; - } - - function dummyMouseHandler() { - } - - function getSpecialEventObject( eventType ) { - var realType = eventType.substr( 1 ); - - return { - setup: function( /* data, namespace */ ) { - // If this is the first virtual mouse binding for this element, - // add a bindings object to its data. - - if ( !hasVirtualBindings( this ) ) { - $.data( this, dataPropertyName, {} ); - } - - // If setup is called, we know it is the first binding for this - // eventType, so initialize the count for the eventType to zero. - var bindings = $.data( this, dataPropertyName ); - bindings[ eventType ] = true; - - // If this is the first virtual mouse event for this type, - // register a global handler on the document. - - activeDocHandlers[ eventType ] = ( activeDocHandlers[ eventType ] || 0 ) + 1; - - if ( activeDocHandlers[ eventType ] === 1 ) { - $document.bind( realType, mouseEventCallback ); - } - - // Some browsers, like Opera Mini, won't dispatch mouse/click events - // for elements unless they actually have handlers registered on them. - // To get around this, we register dummy handlers on the elements. - - $( this ).bind( realType, dummyMouseHandler ); - - // For now, if event capture is not supported, we rely on mouse handlers. - if ( eventCaptureSupported ) { - // If this is the first virtual mouse binding for the document, - // register our touchstart handler on the document. - - activeDocHandlers[ "touchstart" ] = ( activeDocHandlers[ "touchstart" ] || 0 ) + 1; - - if ( activeDocHandlers[ "touchstart" ] === 1 ) { - $document.bind( "touchstart", handleTouchStart ) - .bind( "touchend", handleTouchEnd ) - - // On touch platforms, touching the screen and then dragging your finger - // causes the window content to scroll after some distance threshold is - // exceeded. On these platforms, a scroll prevents a click event from being - // dispatched, and on some platforms, even the touchend is suppressed. To - // mimic the suppression of the click event, we need to watch for a scroll - // event. Unfortunately, some platforms like iOS don't dispatch scroll - // events until *AFTER* the user lifts their finger (touchend). This means - // we need to watch both scroll and touchmove events to figure out whether - // or not a scroll happenens before the touchend event is fired. - - .bind( "touchmove", handleTouchMove ) - .bind( "scroll", handleScroll ); - } - } - }, - - teardown: function( /* data, namespace */ ) { - // If this is the last virtual binding for this eventType, - // remove its global handler from the document. - - --activeDocHandlers[eventType]; - - if ( !activeDocHandlers[ eventType ] ) { - $document.unbind( realType, mouseEventCallback ); - } - - if ( eventCaptureSupported ) { - // If this is the last virtual mouse binding in existence, - // remove our document touchstart listener. - - --activeDocHandlers["touchstart"]; - - if ( !activeDocHandlers[ "touchstart" ] ) { - $document.unbind( "touchstart", handleTouchStart ) - .unbind( "touchmove", handleTouchMove ) - .unbind( "touchend", handleTouchEnd ) - .unbind( "scroll", handleScroll ); - } - } - - var $this = $( this ), - bindings = $.data( this, dataPropertyName ); - - // teardown may be called when an element was - // removed from the DOM. If this is the case, - // jQuery core may have already stripped the element - // of any data bindings so we need to check it before - // using it. - if ( bindings ) { - bindings[ eventType ] = false; - } +(function( $, window, document, undefined ) { + +var dataPropertyName = "virtualMouseBindings", + touchTargetPropertyName = "virtualTouchID", + virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split( " " ), + touchEventProps = "clientX clientY pageX pageY screenX screenY".split( " " ), + mouseHookProps = $.event.mouseHooks ? $.event.mouseHooks.props : [], + mouseEventProps = $.event.props.concat( mouseHookProps ), + activeDocHandlers = {}, + resetTimerID = 0, + startX = 0, + startY = 0, + didScroll = false, + clickBlockList = [], + blockMouseTriggers = false, + blockTouchTriggers = false, + eventCaptureSupported = "addEventListener" in document, + $document = $( document ), + nextTouchID = 1, + lastTouchID = 0, threshold, + i; + +$.vmouse = { + moveDistanceThreshold: 10, + clickDistanceThreshold: 10, + resetTimerDuration: 1500 +}; + +function getNativeEvent( event ) { + + while ( event && typeof event.originalEvent !== "undefined" ) { + event = event.originalEvent; + } + return event; +} + +function createVirtualEvent( event, eventType ) { + + var t = event.type, + oe, props, ne, prop, ct, touch, i, j, len; + + event = $.Event( event ); + event.type = eventType; + + oe = event.originalEvent; + props = $.event.props; + + // addresses separation of $.event.props in to $.event.mouseHook.props and Issue 3280 + // https://github.com/jquery/jquery-mobile/issues/3280 + if ( t.search( /^(mouse|click)/ ) > -1 ) { + props = mouseEventProps; + } + + // copy original event properties over to the new event + // this would happen if we could call $.event.fix instead of $.Event + // but we don't have a way to force an event to be fixed multiple times + if ( oe ) { + for ( i = props.length, prop; i; ) { + prop = props[ --i ]; + event[ prop ] = oe[ prop ]; + } + } + + // make sure that if the mouse and click virtual events are generated + // without a .which one is defined + if ( t.search(/mouse(down|up)|click/) > -1 && !event.which ) { + event.which = 1; + } + + if ( t.search(/^touch/) !== -1 ) { + ne = getNativeEvent( oe ); + t = ne.touches; + ct = ne.changedTouches; + touch = ( t && t.length ) ? t[0] : ( ( ct && ct.length ) ? ct[ 0 ] : undefined ); + + if ( touch ) { + for ( j = 0, len = touchEventProps.length; j < len; j++) { + prop = touchEventProps[ j ]; + event[ prop ] = touch[ prop ]; + } + } + } + + return event; +} + +function getVirtualBindingFlags( element ) { + + var flags = {}, + b, k; + + while ( element ) { + + b = $.data( element, dataPropertyName ); + + for ( k in b ) { + if ( b[ k ] ) { + flags[ k ] = flags.hasVirtualBinding = true; + } + } + element = element.parentNode; + } + return flags; +} + +function getClosestElementWithVirtualBinding( element, eventType ) { + var b; + while ( element ) { + + b = $.data( element, dataPropertyName ); + + if ( b && ( !eventType || b[ eventType ] ) ) { + return element; + } + element = element.parentNode; + } + return null; +} + +function enableTouchBindings() { + blockTouchTriggers = false; +} + +function disableTouchBindings() { + blockTouchTriggers = true; +} + +function enableMouseBindings() { + lastTouchID = 0; + clickBlockList.length = 0; + blockMouseTriggers = false; + + // When mouse bindings are enabled, our + // touch bindings are disabled. + disableTouchBindings(); +} + +function disableMouseBindings() { + // When mouse bindings are disabled, our + // touch bindings are enabled. + enableTouchBindings(); +} + +function startResetTimer() { + clearResetTimer(); + resetTimerID = setTimeout( function() { + resetTimerID = 0; + enableMouseBindings(); + }, $.vmouse.resetTimerDuration ); +} + +function clearResetTimer() { + if ( resetTimerID ) { + clearTimeout( resetTimerID ); + resetTimerID = 0; + } +} + +function triggerVirtualEvent( eventType, event, flags ) { + var ve; + + if ( ( flags && flags[ eventType ] ) || + ( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) { + + ve = createVirtualEvent( event, eventType ); + + $( event.target).trigger( ve ); + } + + return ve; +} + +function mouseEventCallback( event ) { + var touchID = $.data( event.target, touchTargetPropertyName ), + ve; + + if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ) { + ve = triggerVirtualEvent( "v" + event.type, event ); + if ( ve ) { + if ( ve.isDefaultPrevented() ) { + event.preventDefault(); + } + if ( ve.isPropagationStopped() ) { + event.stopPropagation(); + } + if ( ve.isImmediatePropagationStopped() ) { + event.stopImmediatePropagation(); + } + } + } +} + +function handleTouchStart( event ) { + + var touches = getNativeEvent( event ).touches, + target, flags, t; + + if ( touches && touches.length === 1 ) { + + target = event.target; + flags = getVirtualBindingFlags( target ); + + if ( flags.hasVirtualBinding ) { + + lastTouchID = nextTouchID++; + $.data( target, touchTargetPropertyName, lastTouchID ); + + clearResetTimer(); + + disableMouseBindings(); + didScroll = false; + + t = getNativeEvent( event ).touches[ 0 ]; + startX = t.pageX; + startY = t.pageY; + + triggerVirtualEvent( "vmouseover", event, flags ); + triggerVirtualEvent( "vmousedown", event, flags ); + } + } +} + +function handleScroll( event ) { + if ( blockTouchTriggers ) { + return; + } + + if ( !didScroll ) { + triggerVirtualEvent( "vmousecancel", event, getVirtualBindingFlags( event.target ) ); + } + + didScroll = true; + startResetTimer(); +} + +function handleTouchMove( event ) { + if ( blockTouchTriggers ) { + return; + } + + var t = getNativeEvent( event ).touches[ 0 ], + didCancel = didScroll, + moveThreshold = $.vmouse.moveDistanceThreshold, + flags = getVirtualBindingFlags( event.target ); + + didScroll = didScroll || + ( Math.abs( t.pageX - startX ) > moveThreshold || + Math.abs( t.pageY - startY ) > moveThreshold ); + + if ( didScroll && !didCancel ) { + triggerVirtualEvent( "vmousecancel", event, flags ); + } + + triggerVirtualEvent( "vmousemove", event, flags ); + startResetTimer(); +} + +function handleTouchEnd( event ) { + if ( blockTouchTriggers ) { + return; + } + + disableTouchBindings(); + + var flags = getVirtualBindingFlags( event.target ), + ve, t; + triggerVirtualEvent( "vmouseup", event, flags ); + + if ( !didScroll ) { + ve = triggerVirtualEvent( "vclick", event, flags ); + if ( ve && ve.isDefaultPrevented() ) { + // The target of the mouse events that follow the touchend + // event don't necessarily match the target used during the + // touch. This means we need to rely on coordinates for blocking + // any click that is generated. + t = getNativeEvent( event ).changedTouches[ 0 ]; + clickBlockList.push({ + touchID: lastTouchID, + x: t.clientX, + y: t.clientY + }); + + // Prevent any mouse events that follow from triggering + // virtual event notifications. + blockMouseTriggers = true; + } + } + triggerVirtualEvent( "vmouseout", event, flags); + didScroll = false; + + startResetTimer(); +} + +function hasVirtualBindings( ele ) { + var bindings = $.data( ele, dataPropertyName ), + k; + + if ( bindings ) { + for ( k in bindings ) { + if ( bindings[ k ] ) { + return true; + } + } + } + return false; +} + +function dummyMouseHandler() {} + +function getSpecialEventObject( eventType ) { + var realType = eventType.substr( 1 ); + + return { + setup: function(/* data, namespace */) { + // If this is the first virtual mouse binding for this element, + // add a bindings object to its data. + + if ( !hasVirtualBindings( this ) ) { + $.data( this, dataPropertyName, {} ); + } + + // If setup is called, we know it is the first binding for this + // eventType, so initialize the count for the eventType to zero. + var bindings = $.data( this, dataPropertyName ); + bindings[ eventType ] = true; + + // If this is the first virtual mouse event for this type, + // register a global handler on the document. + + activeDocHandlers[ eventType ] = ( activeDocHandlers[ eventType ] || 0 ) + 1; + + if ( activeDocHandlers[ eventType ] === 1 ) { + $document.bind( realType, mouseEventCallback ); + } + + // Some browsers, like Opera Mini, won't dispatch mouse/click events + // for elements unless they actually have handlers registered on them. + // To get around this, we register dummy handlers on the elements. + + $( this ).bind( realType, dummyMouseHandler ); + + // For now, if event capture is not supported, we rely on mouse handlers. + if ( eventCaptureSupported ) { + // If this is the first virtual mouse binding for the document, + // register our touchstart handler on the document. + + activeDocHandlers[ "touchstart" ] = ( activeDocHandlers[ "touchstart" ] || 0) + 1; + + if ( activeDocHandlers[ "touchstart" ] === 1 ) { + $document.bind( "touchstart", handleTouchStart ) + .bind( "touchend", handleTouchEnd ) + + // On touch platforms, touching the screen and then dragging your finger + // causes the window content to scroll after some distance threshold is + // exceeded. On these platforms, a scroll prevents a click event from being + // dispatched, and on some platforms, even the touchend is suppressed. To + // mimic the suppression of the click event, we need to watch for a scroll + // event. Unfortunately, some platforms like iOS don't dispatch scroll + // events until *AFTER* the user lifts their finger (touchend). This means + // we need to watch both scroll and touchmove events to figure out whether + // or not a scroll happenens before the touchend event is fired. + + .bind( "touchmove", handleTouchMove ) + .bind( "scroll", handleScroll ); + } + } + }, + + teardown: function(/* data, namespace */) { + // If this is the last virtual binding for this eventType, + // remove its global handler from the document. + + --activeDocHandlers[ eventType ]; + + if ( !activeDocHandlers[ eventType ] ) { + $document.unbind( realType, mouseEventCallback ); + } + + if ( eventCaptureSupported ) { + // If this is the last virtual mouse binding in existence, + // remove our document touchstart listener. + + --activeDocHandlers[ "touchstart" ]; + + if ( !activeDocHandlers[ "touchstart" ] ) { + $document.unbind( "touchstart", handleTouchStart ) + .unbind( "touchmove", handleTouchMove ) + .unbind( "touchend", handleTouchEnd ) + .unbind( "scroll", handleScroll ); + } + } + + var $this = $( this ), + bindings = $.data( this, dataPropertyName ); + + // teardown may be called when an element was + // removed from the DOM. If this is the case, + // jQuery core may have already stripped the element + // of any data bindings so we need to check it before + // using it. + if ( bindings ) { + bindings[ eventType ] = false; + } - // Unregister the dummy event handler. + // Unregister the dummy event handler. - $this.unbind( realType, dummyMouseHandler ); + $this.unbind( realType, dummyMouseHandler ); - // If this is the last virtual mouse binding on the - // element, remove the binding data from the element. - - if ( !hasVirtualBindings( this ) ) { - $this.removeData( dataPropertyName ); - } - } - }; - } + // If this is the last virtual mouse binding on the + // element, remove the binding data from the element. + + if ( !hasVirtualBindings( this ) ) { + $this.removeData( dataPropertyName ); + } + } + }; +} // Expose our custom events to the jQuery bind/unbind mechanism. - for ( i = 0; i < virtualEventNames.length; i++ ) { - $.event.special[ virtualEventNames[ i ] ] = getSpecialEventObject( virtualEventNames[ i ] ); - } +for ( i = 0; i < virtualEventNames.length; i++ ) { + $.event.special[ virtualEventNames[ i ] ] = getSpecialEventObject( virtualEventNames[ i ] ); +} // Add a capture click handler to block clicks. // Note that we require event capture support for this so if the device // doesn't support it, we punt for now and rely solely on mouse events. - if ( eventCaptureSupported ) { - document.addEventListener( "click", function( e ) { - var cnt = clickBlockList.length, - target = e.target, - x, y, ele, i, o, touchID; - - if ( cnt ) { - x = e.clientX; - y = e.clientY; - threshold = $.vmouse.clickDistanceThreshold; - - // The idea here is to run through the clickBlockList to see if - // the current click event is in the proximity of one of our - // vclick events that had preventDefault() called on it. If we find - // one, then we block the click. - // - // Why do we have to rely on proximity? - // - // Because the target of the touch event that triggered the vclick - // can be different from the target of the click event synthesized - // by the browser. The target of a mouse/click event that is synthesized - // from a touch event seems to be implementation specific. For example, - // some browsers will fire mouse/click events for a link that is near - // a touch event, even though the target of the touchstart/touchend event - // says the user touched outside the link. Also, it seems that with most - // browsers, the target of the mouse/click event is not calculated until the - // time it is dispatched, so if you replace an element that you touched - // with another element, the target of the mouse/click will be the new - // element underneath that point. - // - // Aside from proximity, we also check to see if the target and any - // of its ancestors were the ones that blocked a click. This is necessary - // because of the strange mouse/click target calculation done in the - // Android 2.1 browser, where if you click on an element, and there is a - // mouse/click handler on one of its ancestors, the target will be the - // innermost child of the touched element, even if that child is no where - // near the point of touch. - - ele = target; - - while ( ele ) { - for ( i = 0; i < cnt; i++ ) { - o = clickBlockList[ i ]; - touchID = 0; - - if ( ( ele === target && Math.abs( o.x - x ) < threshold && Math.abs( o.y - y ) < threshold ) || - $.data( ele, touchTargetPropertyName ) === o.touchID ) { - // XXX: We may want to consider removing matches from the block list - // instead of waiting for the reset timer to fire. - e.preventDefault(); - e.stopPropagation(); - return; - } - } - ele = ele.parentNode; - } - } - }, true ); - } - } ); - - /*! - * jQuery Mobile Namespace @VERSION - * http://jquerymobile.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Namespace -//>>group: Core -//>>description: The mobile namespace on the jQuery object - - ( function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( 'ns',[ "jquery" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } - } )( function( $ ) { - - $.mobile = { version: "@VERSION" }; - - return $.mobile; - } ); - - /*! - * jQuery Mobile Touch Support Test @VERSION - * http://jquerymobile.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Touch support test -//>>group: Core -//>>description: Touch feature test - - ( function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( 'support/touch',[ - "jquery", - "../ns" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } - } )( function( $ ) { - - var support = { - touch: "ontouchend" in document - }; - - $.mobile.support = $.mobile.support || {}; - $.extend( $.support, support ); - $.extend( $.mobile.support, support ); - - return $.support; - } ); - - /*! - * jQuery Mobile Touch Events @VERSION - * http://jquerymobile.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Touch -//>>group: Events -//>>description: Touch events including: touchstart, touchmove, touchend, tap, taphold, swipe, swipeleft, swiperight - - ( function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( 'events/touch',[ - "jquery", - "../vmouse", - "../support/touch" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } - } )( function( $ ) { - var $document = $( document ), - supportTouch = $.mobile.support.touch, - touchStartEvent = supportTouch ? "touchstart" : "mousedown", - touchStopEvent = supportTouch ? "touchend" : "mouseup", - touchMoveEvent = supportTouch ? "touchmove" : "mousemove"; - -// setup new event shortcuts - $.each( ( "touchstart touchmove touchend " + - "tap taphold " + - "swipe swipeleft swiperight" ).split( " " ), function( i, name ) { - - $.fn[ name ] = function( fn ) { - return fn ? this.bind( name, fn ) : this.trigger( name ); - }; - - // jQuery < 1.8 - if ( $.attrFn ) { - $.attrFn[ name ] = true; - } - } ); - - function triggerCustomEvent( obj, eventType, event, bubble ) { - var originalType = event.type; - event.type = eventType; - if ( bubble ) { - $.event.trigger( event, undefined, obj ); - } else { - $.event.dispatch.call( obj, event ); - } - event.type = originalType; - } - -// also handles taphold - $.event.special.tap = { - tapholdThreshold: 750, - emitTapOnTaphold: true, - setup: function() { - var thisObject = this, - $this = $( thisObject ), - isTaphold = false; - - $this.bind( "vmousedown", function( event ) { - isTaphold = false; - if ( event.which && event.which !== 1 ) { - return true; - } - - var origTarget = event.target, - timer, clickHandler; - - function clearTapTimer() { - if ( timer ) { - $this.bind( "vclick", clickHandler ); - clearTimeout( timer ); - } - } - - function clearTapHandlers() { - clearTapTimer(); - - $this.unbind( "vclick", clickHandler ) - .unbind( "vmouseup", clearTapTimer ); - $document.unbind( "vmousecancel", clearTapHandlers ); - } - - clickHandler = function( event ) { - clearTapHandlers(); - - // ONLY trigger a 'tap' event if the start target is - // the same as the stop target. - if ( !isTaphold && origTarget === event.target ) { - triggerCustomEvent( thisObject, "tap", event ); - } else if ( isTaphold ) { - event.preventDefault(); - } - }; - - $this.bind( "vmouseup", clearTapTimer ); - - $document.bind( "vmousecancel", clearTapHandlers ); - - timer = setTimeout( function() { - if ( !$.event.special.tap.emitTapOnTaphold ) { - isTaphold = true; - } - timer = 0; - triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) ); - }, $.event.special.tap.tapholdThreshold ); - } ); - }, - teardown: function() { - $( this ).unbind( "vmousedown" ).unbind( "vclick" ).unbind( "vmouseup" ); - $document.unbind( "vmousecancel" ); - } - }; - -// Also handles swipeleft, swiperight - $.event.special.swipe = { - - // More than this horizontal displacement, and we will suppress scrolling. - scrollSupressionThreshold: 30, - - // More time than this, and it isn't a swipe. - durationThreshold: 1000, - - // Swipe horizontal displacement must be more than this. - horizontalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30, - - // Swipe vertical displacement must be less than this. - verticalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30, - - getLocation: function( event ) { - var winPageX = window.pageXOffset, - winPageY = window.pageYOffset, - x = event.clientX, - y = event.clientY; - - if ( event.pageY === 0 && Math.floor( y ) > Math.floor( event.pageY ) || - event.pageX === 0 && Math.floor( x ) > Math.floor( event.pageX ) ) { - - // iOS4 clientX/clientY have the value that should have been - // in pageX/pageY. While pageX/page/ have the value 0 - x = x - winPageX; - y = y - winPageY; - } else if ( y < ( event.pageY - winPageY ) || x < ( event.pageX - winPageX ) ) { - - // Some Android browsers have totally bogus values for clientX/Y - // when scrolling/zooming a page. Detectable since clientX/clientY - // should never be smaller than pageX/pageY minus page scroll - x = event.pageX - winPageX; - y = event.pageY - winPageY; - } - - return { - x: x, - y: y - }; - }, - - start: function( event ) { - var data = event.originalEvent.touches ? - event.originalEvent.touches[ 0 ] : event, - location = $.event.special.swipe.getLocation( data ); - return { - time: ( new Date() ).getTime(), - coords: [ location.x, location.y ], - origin: $( event.target ) - }; - }, - - stop: function( event ) { - var data = event.originalEvent.touches ? - event.originalEvent.touches[ 0 ] : event, - location = $.event.special.swipe.getLocation( data ); - return { - time: ( new Date() ).getTime(), - coords: [ location.x, location.y ] - }; - }, - - handleSwipe: function( start, stop, thisObject, origTarget ) { - if ( stop.time - start.time < $.event.special.swipe.durationThreshold && - Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold && - Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) { - var direction = start.coords[ 0 ] > stop.coords[ 0 ] ? "swipeleft" : "swiperight"; - - triggerCustomEvent( thisObject, "swipe", $.Event( "swipe", { target: origTarget, swipestart: start, swipestop: stop } ), true ); - triggerCustomEvent( thisObject, direction, $.Event( direction, { target: origTarget, swipestart: start, swipestop: stop } ), true ); - return true; - } - return false; - - }, - - // This serves as a flag to ensure that at most one swipe event event is - // in work at any given time - eventInProgress: false, - - setup: function() { - var events, - thisObject = this, - $this = $( thisObject ), - context = {}; - - // Retrieve the events data for this element and add the swipe context - events = $.data( this, "mobile-events" ); - if ( !events ) { - events = { length: 0 }; - $.data( this, "mobile-events", events ); - } - events.length++; - events.swipe = context; - - context.start = function( event ) { - - // Bail if we're already working on a swipe event - if ( $.event.special.swipe.eventInProgress ) { - return; - } - $.event.special.swipe.eventInProgress = true; - - var stop, - start = $.event.special.swipe.start( event ), - origTarget = event.target, - emitted = false; - - context.move = function( event ) { - if ( !start || event.isDefaultPrevented() ) { - return; - } - - stop = $.event.special.swipe.stop( event ); - if ( !emitted ) { - emitted = $.event.special.swipe.handleSwipe( start, stop, thisObject, origTarget ); - if ( emitted ) { - - // Reset the context to make way for the next swipe event - $.event.special.swipe.eventInProgress = false; - } - } - // prevent scrolling - if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) { - event.preventDefault(); - } - }; - - context.stop = function() { - emitted = true; - - // Reset the context to make way for the next swipe event - $.event.special.swipe.eventInProgress = false; - $document.off( touchMoveEvent, context.move ); - context.move = null; - }; - - $document.on( touchMoveEvent, context.move ) - .one( touchStopEvent, context.stop ); - }; - $this.on( touchStartEvent, context.start ); - }, - - teardown: function() { - var events, context; - - events = $.data( this, "mobile-events" ); - if ( events ) { - context = events.swipe; - delete events.swipe; - events.length--; - if ( events.length === 0 ) { - $.removeData( this, "mobile-events" ); - } - } - - if ( context ) { - if ( context.start ) { - $( this ).off( touchStartEvent, context.start ); - } - if ( context.move ) { - $document.off( touchMoveEvent, context.move ); - } - if ( context.stop ) { - $document.off( touchStopEvent, context.stop ); - } - } - } - }; - $.each( { - taphold: "tap", - swipeleft: "swipe.left", - swiperight: "swipe.right" - }, function( event, sourceEvent ) { - - $.event.special[ event ] = { - setup: function() { - $( this ).bind( sourceEvent, $.noop ); - }, - teardown: function() { - $( this ).unbind( sourceEvent ); - } - }; - } ); - - return $.event.special; - } ); - +if ( eventCaptureSupported ) { + document.addEventListener( "click", function( e ) { + var cnt = clickBlockList.length, + target = e.target, + x, y, ele, i, o, touchID; + + if ( cnt ) { + x = e.clientX; + y = e.clientY; + threshold = $.vmouse.clickDistanceThreshold; + + // The idea here is to run through the clickBlockList to see if + // the current click event is in the proximity of one of our + // vclick events that had preventDefault() called on it. If we find + // one, then we block the click. + // + // Why do we have to rely on proximity? + // + // Because the target of the touch event that triggered the vclick + // can be different from the target of the click event synthesized + // by the browser. The target of a mouse/click event that is synthesized + // from a touch event seems to be implementation specific. For example, + // some browsers will fire mouse/click events for a link that is near + // a touch event, even though the target of the touchstart/touchend event + // says the user touched outside the link. Also, it seems that with most + // browsers, the target of the mouse/click event is not calculated until the + // time it is dispatched, so if you replace an element that you touched + // with another element, the target of the mouse/click will be the new + // element underneath that point. + // + // Aside from proximity, we also check to see if the target and any + // of its ancestors were the ones that blocked a click. This is necessary + // because of the strange mouse/click target calculation done in the + // Android 2.1 browser, where if you click on an element, and there is a + // mouse/click handler on one of its ancestors, the target will be the + // innermost child of the touched element, even if that child is no where + // near the point of touch. + + ele = target; + + while ( ele ) { + for ( i = 0; i < cnt; i++ ) { + o = clickBlockList[ i ]; + touchID = 0; + + if ( ( ele === target && Math.abs( o.x - x ) < threshold && Math.abs( o.y - y ) < threshold ) || + $.data( ele, touchTargetPropertyName ) === o.touchID ) { + // XXX: We may want to consider removing matches from the block list + // instead of waiting for the reset timer to fire. + e.preventDefault(); + e.stopPropagation(); + return; + } + } + ele = ele.parentNode; + } + } + }, true); +} +})( jQuery, window, document ); + +(function( $ ) { + $.mobile = {}; +}( jQuery )); + + (function( $, undefined ) { + var support = { + touch: "ontouchend" in document + }; + + $.mobile.support = $.mobile.support || {}; + $.extend( $.support, support ); + $.extend( $.mobile.support, support ); + }( jQuery )); + + +(function( $, window, undefined ) { + var $document = $( document ), + supportTouch = $.mobile.support.touch, + scrollEvent = "touchmove scroll", + touchStartEvent = supportTouch ? "touchstart" : "mousedown", + touchStopEvent = supportTouch ? "touchend" : "mouseup", + touchMoveEvent = supportTouch ? "touchmove" : "mousemove"; + + // setup new event shortcuts + $.each( ( "touchstart touchmove touchend " + + "tap taphold " + + "swipe swipeleft swiperight " + + "scrollstart scrollstop" ).split( " " ), function( i, name ) { + + $.fn[ name ] = function( fn ) { + return fn ? this.bind( name, fn ) : this.trigger( name ); + }; + + // jQuery < 1.8 + if ( $.attrFn ) { + $.attrFn[ name ] = true; + } + }); + + function triggerCustomEvent( obj, eventType, event, bubble ) { + var originalType = event.type; + event.type = eventType; + if ( bubble ) { + $.event.trigger( event, undefined, obj ); + } else { + $.event.dispatch.call( obj, event ); + } + event.type = originalType; + } + + // also handles scrollstop + $.event.special.scrollstart = { + + enabled: true, + setup: function() { + + var thisObject = this, + $this = $( thisObject ), + scrolling, + timer; + + function trigger( event, state ) { + scrolling = state; + triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event ); + } + + // iPhone triggers scroll after a small delay; use touchmove instead + $this.bind( scrollEvent, function( event ) { + + if ( !$.event.special.scrollstart.enabled ) { + return; + } + + if ( !scrolling ) { + trigger( event, true ); + } + + clearTimeout( timer ); + timer = setTimeout( function() { + trigger( event, false ); + }, 50 ); + }); + }, + teardown: function() { + $( this ).unbind( scrollEvent ); + } + }; + + // also handles taphold + $.event.special.tap = { + tapholdThreshold: 750, + emitTapOnTaphold: true, + setup: function() { + var thisObject = this, + $this = $( thisObject ), + isTaphold = false; + + $this.bind( "vmousedown", function( event ) { + isTaphold = false; + if ( event.which && event.which !== 1 ) { + return false; + } + + var origTarget = event.target, + timer; + + function clearTapTimer() { + clearTimeout( timer ); + } + + function clearTapHandlers() { + clearTapTimer(); + + $this.unbind( "vclick", clickHandler ) + .unbind( "vmouseup", clearTapTimer ); + $document.unbind( "vmousecancel", clearTapHandlers ); + } + + function clickHandler( event ) { + clearTapHandlers(); + + // ONLY trigger a 'tap' event if the start target is + // the same as the stop target. + if ( !isTaphold && origTarget === event.target ) { + triggerCustomEvent( thisObject, "tap", event ); + } else if ( isTaphold ) { + event.preventDefault(); + } + } + + $this.bind( "vmouseup", clearTapTimer ) + .bind( "vclick", clickHandler ); + $document.bind( "vmousecancel", clearTapHandlers ); + + timer = setTimeout( function() { + if ( !$.event.special.tap.emitTapOnTaphold ) { + isTaphold = true; + } + triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) ); + }, $.event.special.tap.tapholdThreshold ); + }); + }, + teardown: function() { + $( this ).unbind( "vmousedown" ).unbind( "vclick" ).unbind( "vmouseup" ); + $document.unbind( "vmousecancel" ); + } + }; + + // Also handles swipeleft, swiperight + $.event.special.swipe = { + + // More than this horizontal displacement, and we will suppress scrolling. + scrollSupressionThreshold: 30, + + // More time than this, and it isn't a swipe. + durationThreshold: 1000, + + // Swipe horizontal displacement must be more than this. + horizontalDistanceThreshold: 30, + + // Swipe vertical displacement must be less than this. + verticalDistanceThreshold: 30, + + getLocation: function ( event ) { + var winPageX = window.pageXOffset, + winPageY = window.pageYOffset, + x = event.clientX, + y = event.clientY; + + if ( event.pageY === 0 && Math.floor( y ) > Math.floor( event.pageY ) || + event.pageX === 0 && Math.floor( x ) > Math.floor( event.pageX ) ) { + + // iOS4 clientX/clientY have the value that should have been + // in pageX/pageY. While pageX/page/ have the value 0 + x = x - winPageX; + y = y - winPageY; + } else if ( y < ( event.pageY - winPageY) || x < ( event.pageX - winPageX ) ) { + + // Some Android browsers have totally bogus values for clientX/Y + // when scrolling/zooming a page. Detectable since clientX/clientY + // should never be smaller than pageX/pageY minus page scroll + x = event.pageX - winPageX; + y = event.pageY - winPageY; + } + + return { + x: x, + y: y + }; + }, + + start: function( event ) { + var data = event.originalEvent.touches ? + event.originalEvent.touches[ 0 ] : event, + location = $.event.special.swipe.getLocation( data ); + return { + time: ( new Date() ).getTime(), + coords: [ location.x, location.y ], + origin: $( event.target ) + }; + }, + + stop: function( event ) { + var data = event.originalEvent.touches ? + event.originalEvent.touches[ 0 ] : event, + location = $.event.special.swipe.getLocation( data ); + return { + time: ( new Date() ).getTime(), + coords: [ location.x, location.y ] + }; + }, + + handleSwipe: function( start, stop, thisObject, origTarget ) { + if ( stop.time - start.time < $.event.special.swipe.durationThreshold && + Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold && + Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) { + var direction = start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight"; + + triggerCustomEvent( thisObject, "swipe", $.Event( "swipe", { target: origTarget, swipestart: start, swipestop: stop }), true ); + triggerCustomEvent( thisObject, direction,$.Event( direction, { target: origTarget, swipestart: start, swipestop: stop } ), true ); + return true; + } + return false; + + }, + + // This serves as a flag to ensure that at most one swipe event event is + // in work at any given time + eventInProgress: false, + + setup: function() { + var events, + thisObject = this, + $this = $( thisObject ), + context = {}; + + // Retrieve the events data for this element and add the swipe context + events = $.data( this, "mobile-events" ); + if ( !events ) { + events = { length: 0 }; + $.data( this, "mobile-events", events ); + } + events.length++; + events.swipe = context; + + context.start = function( event ) { + + // Bail if we're already working on a swipe event + if ( $.event.special.swipe.eventInProgress ) { + return; + } + $.event.special.swipe.eventInProgress = true; + + var stop, + start = $.event.special.swipe.start( event ), + origTarget = event.target, + emitted = false; + + context.move = function( event ) { + if ( !start ) { + return; + } + + stop = $.event.special.swipe.stop( event ); + if ( !emitted ) { + emitted = $.event.special.swipe.handleSwipe( start, stop, thisObject, origTarget ); + if ( emitted ) { + + // Reset the context to make way for the next swipe event + $.event.special.swipe.eventInProgress = false; + } + } + // prevent scrolling + if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) { + event.preventDefault(); + } + }; + + context.stop = function() { + emitted = true; + + // Reset the context to make way for the next swipe event + $.event.special.swipe.eventInProgress = false; + $document.off( touchMoveEvent, context.move ); + context.move = null; + }; + + $document.on( touchMoveEvent, context.move ) + .one( touchStopEvent, context.stop ); + }; + $this.on( touchStartEvent, context.start ); + }, + + teardown: function() { + var events, context; + + events = $.data( this, "mobile-events" ); + if ( events ) { + context = events.swipe; + delete events.swipe; + events.length--; + if ( events.length === 0 ) { + $.removeData( this, "mobile-events" ); + } + } + + if ( context ) { + if ( context.start ) { + $( this ).off( touchStartEvent, context.start ); + } + if ( context.move ) { + $document.off( touchMoveEvent, context.move ); + } + if ( context.stop ) { + $document.off( touchStopEvent, context.stop ); + } + } + } + }; + $.each({ + scrollstop: "scrollstart", + taphold: "tap", + swipeleft: "swipe.left", + swiperight: "swipe.right" + }, function( event, sourceEvent ) { + + $.event.special[ event ] = { + setup: function() { + $( this ).bind( sourceEvent, $.noop ); + }, + teardown: function() { + $( this ).unbind( sourceEvent ); + } + }; + }); + +})( jQuery, this ); })); From 66198844e9a8653b3f53b63588d7b071daf65589 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Thu, 11 Oct 2018 17:20:25 +0300 Subject: [PATCH 259/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Block/DataProviders/ImageUploadConfig.php | 8 ++++---- app/code/Magento/Backend/Block/Media/Uploader.php | 12 ++++++------ ...{ImageUploadConfig.php => UploadResizeConfig.php} | 2 +- ...Interface.php => UploadResizeConfigInterface.php} | 4 ++-- app/code/Magento/Backend/etc/adminhtml/di.xml | 2 +- app/code/Magento/Backend/etc/adminhtml/system.xml | 4 ++-- .../Backend/view/adminhtml/web/js/media-uploader.js | 8 +++----- app/code/Magento/Catalog/etc/adminhtml/system.xml | 2 +- .../Magento/Framework/Image/Adapter/Config.php | 4 ++-- .../Image/Adapter/UploadConfigInterface.php | 4 ++-- 10 files changed, 24 insertions(+), 26 deletions(-) rename app/code/Magento/Backend/Model/Image/{ImageUploadConfig.php => UploadResizeConfig.php} (96%) rename app/code/Magento/Backend/Model/Image/{ImageUploadConfigInterface.php => UploadResizeConfigInterface.php} (89%) diff --git a/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php b/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php index 6ec40cfa0b2d4..9c17b0e5538f4 100644 --- a/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php +++ b/app/code/Magento/Backend/Block/DataProviders/ImageUploadConfig.php @@ -8,7 +8,7 @@ namespace Magento\Backend\Block\DataProviders; use Magento\Framework\View\Element\Block\ArgumentInterface; -use Magento\Backend\Model\Image\ImageUploadConfigInterface; +use Magento\Backend\Model\Image\UploadResizeConfigInterface; /** * Provides additional data for image uploader @@ -16,14 +16,14 @@ class ImageUploadConfig implements ArgumentInterface { /** - * @var ImageUploadConfigInterface + * @var UploadResizeConfigInterface */ private $imageUploadConfig; /** - * @param ImageUploadConfigInterface $imageUploadConfig + * @param UploadResizeConfigInterface $imageUploadConfig */ - public function __construct(ImageUploadConfigInterface $imageUploadConfig) + public function __construct(UploadResizeConfigInterface $imageUploadConfig) { $this->imageUploadConfig = $imageUploadConfig; } diff --git a/app/code/Magento/Backend/Block/Media/Uploader.php b/app/code/Magento/Backend/Block/Media/Uploader.php index 941d6f37737fe..84fa487281ac8 100644 --- a/app/code/Magento/Backend/Block/Media/Uploader.php +++ b/app/code/Magento/Backend/Block/Media/Uploader.php @@ -10,7 +10,7 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\Image\Adapter\UploadConfigInterface; -use Magento\Backend\Model\Image\ImageUploadConfigInterface; +use Magento\Backend\Model\Image\UploadResizeConfigInterface; /** * Adminhtml media library uploader @@ -40,14 +40,14 @@ class Uploader extends \Magento\Backend\Block\Widget private $jsonEncoder; /** - * @var ImageUploadConfigInterface + * @var UploadResizeConfigInterface */ private $imageUploadConfig; /** * @var UploadConfigInterface * @deprecated - * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface + * @see \Magento\Backend\Model\Image\UploadResizeConfigInterface */ private $imageConfig; @@ -57,7 +57,7 @@ class Uploader extends \Magento\Backend\Block\Widget * @param array $data * @param Json $jsonEncoder * @param UploadConfigInterface $imageConfig - * @param ImageUploadConfigInterface $imageUploadConfig + * @param UploadResizeConfigInterface $imageUploadConfig */ public function __construct( \Magento\Backend\Block\Template\Context $context, @@ -65,14 +65,14 @@ public function __construct( array $data = [], Json $jsonEncoder = null, UploadConfigInterface $imageConfig = null, - ImageUploadConfigInterface $imageUploadConfig = null + UploadResizeConfigInterface $imageUploadConfig = null ) { $this->_fileSizeService = $fileSize; $this->jsonEncoder = $jsonEncoder ?: ObjectManager::getInstance()->get(Json::class); $this->imageConfig = $imageConfig ?: ObjectManager::getInstance()->get(UploadConfigInterface::class); $this->imageUploadConfig = $imageUploadConfig - ?: ObjectManager::getInstance()->get(ImageUploadConfigInterface::class); + ?: ObjectManager::getInstance()->get(UploadResizeConfigInterface::class); parent::__construct($context, $data); } diff --git a/app/code/Magento/Backend/Model/Image/ImageUploadConfig.php b/app/code/Magento/Backend/Model/Image/UploadResizeConfig.php similarity index 96% rename from app/code/Magento/Backend/Model/Image/ImageUploadConfig.php rename to app/code/Magento/Backend/Model/Image/UploadResizeConfig.php index b7e13b1e8274c..8155aa5e2fe2d 100644 --- a/app/code/Magento/Backend/Model/Image/ImageUploadConfig.php +++ b/app/code/Magento/Backend/Model/Image/UploadResizeConfig.php @@ -10,7 +10,7 @@ /** * Image uploader config provider. */ -class ImageUploadConfig implements ImageUploadConfigInterface +class UploadResizeConfig implements UploadResizeConfigInterface { /** * Config path for the maximal image width value diff --git a/app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php b/app/code/Magento/Backend/Model/Image/UploadResizeConfigInterface.php similarity index 89% rename from app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php rename to app/code/Magento/Backend/Model/Image/UploadResizeConfigInterface.php index 254a13407b2c1..50582dfafbcd1 100644 --- a/app/code/Magento/Backend/Model/Image/ImageUploadConfigInterface.php +++ b/app/code/Magento/Backend/Model/Image/UploadResizeConfigInterface.php @@ -8,11 +8,11 @@ namespace Magento\Backend\Model\Image; /** - * Interface ImageUploadConfigInterface + * Interface UploadResizeConfigInterface * * Used to retrieve configuration for frontend image uploader */ -interface ImageUploadConfigInterface +interface UploadResizeConfigInterface { /** * Get maximal width value for resized image diff --git a/app/code/Magento/Backend/etc/adminhtml/di.xml b/app/code/Magento/Backend/etc/adminhtml/di.xml index dcfc99cfed310..4abea272c5495 100644 --- a/app/code/Magento/Backend/etc/adminhtml/di.xml +++ b/app/code/Magento/Backend/etc/adminhtml/di.xml @@ -168,5 +168,5 @@ </arguments> </type> <preference for="CsrfRequestValidator" type="Magento\Backend\App\Request\BackendValidator" /> - <preference for="Magento\Backend\Model\Image\ImageUploadConfigInterface" type="Magento\Backend\Model\Image\ImageUploadConfig" /> + <preference for="Magento\Backend\Model\Image\UploadResizeConfigInterface" type="Magento\Backend\Model\Image\UploadResizeConfig" /> </config> diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index 3a0d3e50acc5a..2915d8d671a01 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -339,9 +339,9 @@ <group id="upload_configuration" translate="label" type="text" sortOrder="1000" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Images Upload Configuration</label> <field id="enable_resize" translate="label" type="select" sortOrder="200" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> - <label>Enable Front-end Resize</label> + <label>Enable Frontend Resize</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> - <comment>Resize performed by javascript during file upload.</comment> + <comment>Resize performed via javascript before file upload.</comment> </field> <field id="max_width" translate="label comment" type="text" sortOrder="300" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Maximum Width</label> diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js index e1d5a0a9debe5..119e7a35747cb 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js +++ b/app/code/Magento/Backend/view/adminhtml/web/js/media-uploader.js @@ -33,8 +33,7 @@ define([ * @private */ _create: function () { - var - self = this, + var self = this, progressTmpl = mageTemplate('[data-template="uploader"]'), isResizeEnabled = this.options.isResizeEnabled, resizeConfiguration = { @@ -43,7 +42,7 @@ define([ maxHeight: this.options.maxHeight }; - if (isResizeEnabled === 0) { + if (!isResizeEnabled) { resizeConfiguration = { action: 'resize' }; @@ -64,8 +63,7 @@ define([ * @param {Object} data */ add: function (e, data) { - var - fileSize, + var fileSize, tmpl; $.each(data.files, function (index, file) { diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml index 2d872fc06b416..74661acb8f136 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/system.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml @@ -207,7 +207,7 @@ <field id="jpeg_quality" translate="label comment" type="text" sortOrder="100" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Quality</label> <validate>validate-greater-than-zero validate-number required-entry digits-range-1-100</validate> - <comment>Jpeg quality for images 1-100%.</comment> + <comment>Jpeg quality for resized images 1-100%.</comment> </field> </group> </section> diff --git a/lib/internal/Magento/Framework/Image/Adapter/Config.php b/lib/internal/Magento/Framework/Image/Adapter/Config.php index 84b6b6dcfbdd1..636bbcdcbdb41 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Config.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Config.php @@ -66,7 +66,7 @@ public function getAdapters() * * @return int * @deprecated - * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface::getMaxHeight() + * @see \Magento\Backend\Model\Image\UploadResizeConfigInterface::getMaxHeight() */ public function getMaxWidth(): int { @@ -78,7 +78,7 @@ public function getMaxWidth(): int * * @return int * @deprecated - * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface::getMaxHeight() + * @see \Magento\Backend\Model\Image\UploadResizeConfigInterface::getMaxHeight() */ public function getMaxHeight(): int { diff --git a/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php b/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php index 990062b83ef6f..0a2dbefff8ee0 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php +++ b/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php @@ -9,8 +9,8 @@ /** * Interface UploadConfigInterface - * @deprecated because new interface was introduced - * @see \Magento\Backend\Model\Image\ImageUploadConfigInterface; + * @deprecated moved to proper namespace and extended + * @see \Magento\Backend\Model\Image\UploadResizeConfigInterface; */ interface UploadConfigInterface { From ad0934a8aaab00bd612206e63d99d4ac2c555131 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Thu, 11 Oct 2018 09:43:53 -0500 Subject: [PATCH 260/812] MAGETWO-95238: Cannot reset customer password from Admin Panel - updated test after CR comments --- .../Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml index cff605d7c907f..0ca1d72a3ae1d 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml @@ -23,7 +23,7 @@ </before> <after> <deleteData createDataKey="customer" stepKey="deleteCustomer"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="logout"/> </after> <!--Edit customer info--> <actionGroup ref="OpenEditCustomerFromAdminActionGroup" stepKey="OpenEditCustomerFrom"> From 2cb6a021a85045167c1affc365ce66670a8aaea7 Mon Sep 17 00:00:00 2001 From: duhon <duhon@rambler.ru> Date: Thu, 11 Oct 2018 17:53:55 +0300 Subject: [PATCH 261/812] MAGETWO-95652: Call to \Magento\Framework\Api\MetadataServiceInterface::getCustomAttributesMetadata leads to fatal error --- .../Model/FilterProductCustomAttribute.php | 2 +- app/code/Magento/Catalog/Model/Product.php | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php b/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php index 830b974e5edb2..497ed2fd49953 100644 --- a/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php +++ b/app/code/Magento/Catalog/Model/FilterProductCustomAttribute.php @@ -28,7 +28,7 @@ public function __construct(array $blackList = []) /** * Delete custom attribute * - * @param array $attributes + * @param array $attributes set objects attributes @example ['attribute_code'=>'attribute_object'] * @return array */ public function execute(array $attributes): array diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index b29eee9a47f8b..5a00f8bfbee8a 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -506,13 +506,16 @@ protected function _getResource() protected function getCustomAttributesCodes() { if ($this->customAttributesCodes === null) { - $this->customAttributesCodes = array_keys($this->eavConfig->getEntityAttributes( - self::ENTITY, - $this - )); - - $this->customAttributesCodes = $this->filterCustomAttribute->execute($this->customAttributesCodes); - $this->customAttributesCodes = array_diff($this->customAttributesCodes, ProductInterface::ATTRIBUTES); + $this->customAttributesCodes = array_diff( + array_keys( + $this->filterCustomAttribute->execute( + $this->eavConfig->getEntityAttributes( + self::ENTITY, + $this + ) + ) + ), ProductInterface::ATTRIBUTES + ); } return $this->customAttributesCodes; From 2eb844f239c68591a6998d279103246609ef4a3d Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Thu, 11 Oct 2018 18:19:10 +0300 Subject: [PATCH 262/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- app/code/Magento/Catalog/Model/Product/Image.php | 6 +++--- .../view/adminhtml/templates/browser/content/uploader.phtml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php index adde1263e1bf9..a0be36c5a327c 100644 --- a/app/code/Magento/Catalog/Model/Product/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Image.php @@ -45,7 +45,7 @@ class Image extends \Magento\Framework\Model\AbstractModel * Default quality value (for JPEG images only). * * @var int - * @deprecated + * @deprecated use config setting with path self::XML_PATH_JPEG_QUALITY */ protected $_quality = null; @@ -220,7 +220,7 @@ class Image extends \Magento\Framework\Model\AbstractModel * @param SerializerInterface $serializer * @param ParamsBuilder $paramsBuilder * @SuppressWarnings(PHPMD.ExcessiveParameterList) - * @SuppressWarnings(PHPMD.UnusedLocalVariable)1 + * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function __construct( \Magento\Framework\Model\Context $context, @@ -305,7 +305,7 @@ public function getHeight() * * @param int $quality * @return $this - * @deprecated + * @deprecated use config setting with path self::XML_PATH_JPEG_QUALITY */ public function setQuality($quality) { diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml index 54f42bb4ecc1f..df0a74c48ac23 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml @@ -17,7 +17,7 @@ foreach ($filters as $media_type) { }, $media_type['files'])); } -$resizeConfig = ($block->getImageUploadConfigData()->getIsResizeEnabled()) +$resizeConfig = $block->getImageUploadConfigData()->getIsResizeEnabled() ? "{action: 'resize', maxWidth: " . $block->getImageUploadMaxWidth() . ", maxHeight: " From 0eec64f51cd9ea437fb75dbf66adccffb5bccac1 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Thu, 11 Oct 2018 18:33:15 +0300 Subject: [PATCH 263/812] MAGETWO-94438: AdminAddImageToWYSIWYGProductTest is unstable - Stabilize test --- .../Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml index 37c0eb6ea1253..03f3e93bb30ec 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGProductTest.xml @@ -47,9 +47,9 @@ <conditionalClick selector="{{ProductDescriptionWYSIWYGToolbarSection.WysiwygArrow}}" dependentSelector="{{ProductDescriptionWYSIWYGToolbarSection.checkIfWysiwygArrowExpand}}" stepKey="clickWysiwygArrowIfClosed" visible="true"/> <waitForText userInput="{{ImageFolder.name}}" stepKey="waitForNewFolder1" /> <click userInput="{{ImageFolder.name}}" stepKey="clickOnCreatedFolder1" /> - <waitForLoadingMaskToDisappear stepKey="waitForLoading4" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoading4" timeout="45"/> <attachFile selector="{{ProductDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload1.value}}" stepKey="uploadImage1"/> - <waitForLoadingMaskToDisappear stepKey="waitForFileUpload1" /> + <waitForLoadingMaskToDisappear stepKey="waitForFileUpload1" timeout="30"/> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="waitForUploadImage1" /> <seeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.imageSelected(ImageUpload1.value)}}" stepKey="seeImageSelected1" /> <see selector="{{ProductDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn1"/> @@ -60,7 +60,7 @@ <dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="dontSeeImage1" /> <dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn2" /> <attachFile selector="{{ProductDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload1.value}}" stepKey="uploadImage2"/> - <waitForLoadingMaskToDisappear stepKey="waitForFileUpload2" /> + <waitForLoadingMaskToDisappear stepKey="waitForFileUpload2" timeout="45"/> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.image(ImageUpload1.value)}}" stepKey="waitForUploadImage2" /> <click selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="clickInsertBtn1" /> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.ImageDescription}}" stepKey="waitForImageDescriptionButton1" /> @@ -72,10 +72,12 @@ <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.Browse}}" stepKey="clickBrowse2" /> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.CancelBtn}}" stepKey="waitForCancelButton2"/> <see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.CancelBtn}}" userInput="Cancel" stepKey="seeCancelBtn2" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoading13" timeout="30"/> <see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.CreateFolder}}" userInput="Create Folder" stepKey="seeCreateFolderBtn2" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoading14" timeout="40"/> <dontSeeElement selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn3" /> <attachFile selector="{{ProductShortDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload3.value}}" stepKey="uploadImage3"/> - <waitForLoadingMaskToDisappear stepKey="waitForFileUpload3" /> + <waitForLoadingMaskToDisappear stepKey="waitForFileUpload3" timeout="45"/> <waitForElementVisible selector="{{ProductShortDescriptionWYSIWYGToolbarSection.image(ImageUpload3.value)}}" stepKey="waitForUploadImage3" /> <waitForElement selector="{{ProductShortDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" stepKey="waitForDeletebtn" /> <see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn2"/> @@ -84,7 +86,7 @@ <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmDelete2" /> <dontSeeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="dontSeeAddSelectedBtn4" /> <attachFile selector="{{ProductShortDescriptionWYSIWYGToolbarSection.BrowseUploadImage}}" userInput="{{ImageUpload3.value}}" stepKey="uploadImage4"/> - <waitForLoadingMaskToDisappear stepKey="waitForFileUpload4" /> + <waitForLoadingMaskToDisappear stepKey="waitForFileUpload4" timeout="45"/> <waitForElementVisible selector="{{ProductShortDescriptionWYSIWYGToolbarSection.image(ImageUpload3.value)}}" stepKey="waitForUploadImage4" /> <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertFile}}" stepKey="clickInsertBtn" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading11" /> From fc5c571ab6e635a17ea7c5a4d4a0209c56ec9366 Mon Sep 17 00:00:00 2001 From: avattam <> Date: Thu, 11 Oct 2018 10:47:21 -0500 Subject: [PATCH 264/812] MAGETWO-95111: Added MFTF test added for this bug fix --- .../Mftf/Section/AdminStoresGridSection.xml | 1 + .../Test/AdminCreateStoreViewCodeTest.xml | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml index 04cbeb5bc596e..6b2c38502923a 100644 --- a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml +++ b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml @@ -12,6 +12,7 @@ <element name="createWebsite" type="button" selector="#add"/> </section> <section name="AdminStoresGridSection"> + <element name="loadingMask" type="text" selector=".admin__data-grid-loading-mask[data-component*='notification_area.notification_area.columns']"/> <element name="storeGrpFilterTextField" type="input" selector="#storeGrid_filter_group_title"/> <element name="websiteFilterTextField" type="input" selector="#storeGrid_filter_website_title"/> <element name="storeFilterTextField" type="input" selector="#storeGrid_filter_store_title"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml new file mode 100644 index 0000000000000..473b0c1663033 --- /dev/null +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<!-- Test XML Example --> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateStoreViewCodeTest"> + <annotations> + <features value="Store"/> + <stories value="Create a store view new in admin"/> + <title value="Admin should be able to create a store view new"/> + <description value="Admin should be able to create a store view new"/> + <group value="storeViewGroup"/> + <severity value="AVERAGE"/> + </annotations> + <before> + <actionGroup ref="LoginActionGroup" stepKey="login"/> + </before> + <amOnPage url="{{AdminSystemStoreViewPage.url}}" stepKey="navigateToNewStoreView"/> + <waitForPageLoad stepKey="waitForPageLoad1" /> + <!--Create Store View and and check for loading-mask!--> + <fillField selector="{{AdminNewStoreSection.storeNameTextField}}" userInput="{{customStore.name}}" stepKey="enterStoreViewName" /> + <fillField selector="{{AdminNewStoreSection.storeCodeTextField}}" userInput="{{customStore.code}}" stepKey="enterStoreViewCode" /> + <selectOption selector="{{AdminNewStoreSection.statusDropdown}}" userInput="Enabled" stepKey="setStatus" /> + <click selector="{{AdminNewStoreViewActionsSection.saveButton}}" stepKey="clickSaveStoreView" /> + <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> + <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> + <waitForPageLoad time="60" stepKey="wait1"/> + <waitForElementNotVisible selector="{{AdminStoresGridSection.loadingMask}}" stepKey="waitForLoadingMaskToLoad"/> + <waitForLoadingMaskToDisappear stepKey="waitForGridLoad"/> + <waitForPageLoad time="60" stepKey="wait2"/> + <waitForElementVisible selector="{{AdminStoresGridSection.websiteFilterTextField}}" stepKey="waitForStoreGridToReload2"/> + <see userInput="You saved the store view." stepKey="seeSavedMessage" /> + </test> +</tests> From 87dce54dc6d75dd203af95a5fe87a1baad236957 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 11 Oct 2018 11:02:38 -0500 Subject: [PATCH 265/812] MAGETWO-95483: Can't delete a cart entry when the cart has a shipping address - Removed all shipping addresses in reset plugin to avoid logical errors --- .../Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php b/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php index 3791b28917e97..a63072f5a3de7 100644 --- a/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php +++ b/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php @@ -27,6 +27,11 @@ public function afterRemoveItem(Quote $quote, Quote $result, $itemId): Quote if (empty($result->getAllVisibleItems())) { foreach ($result->getAllAddresses() as $address) { $result->removeAddress($address->getId()); + + $extensionAttributes = $result->getExtensionAttributes(); + if (!$result->isVirtual() && $extensionAttributes && $extensionAttributes->getShippingAssignments()) { + $extensionAttributes->setShippingAssignments([]); + } } } From 0ec20f5a77fd11fc61d6a0d297bbd6ab09296a78 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 11 Oct 2018 11:16:23 -0500 Subject: [PATCH 266/812] MAGETWO-95588: Swatches on category page does not work - CR feedback --- .../Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml index dd497cca2c2de..0e294153e881e 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateImageSwatchTest.xml @@ -23,7 +23,8 @@ <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <actionGroup ref="logout" stepKey="logout"/> </after> <!-- Begin creating a new product attribute of type "Image Swatch" --> From a19990e4dd46b264d376b485bb28cdfedc2e3e20 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 11 Oct 2018 11:17:50 -0500 Subject: [PATCH 267/812] MAGETWO-71675: Customer can't see available Payment Method for specific country --- .../Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml index 5ed6ba0f79f65..1ef7403e94ce1 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml @@ -199,7 +199,7 @@ <stories value="Checkout flow if payment solutions are not available"/> <title value="Checkout via Customer Checkout with restricted countries for payment"/> <description value="Should be able to place an order as a Customer with restricted countries for payment."/> - <severity value="CRITICAL"/> + <severity value="MAJOR"/> <testCaseId value="MAGETWO-42653"/> <group value="checkout"/> </annotations> @@ -213,7 +213,7 @@ <createData entity="Simple_US_Customer" stepKey="simpleuscustomer"/> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> <magentoCLI stepKey="allowSpecificValue" command="config:set payment/checkmo/allowspecific 0" /> From de9603e744996a3bd2de090ddb1613e597edec0e Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Thu, 11 Oct 2018 13:27:58 -0500 Subject: [PATCH 268/812] MQE-1304: MFTF test failures between 5pm PDT and midnight PDT --- .../Test/Mftf/Section/AdminCartPriceRulesFormSection.xml | 2 ++ .../SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml | 1 + .../Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml | 1 + .../Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml | 1 + .../Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml | 1 + .../Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml | 1 + .../Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml | 1 + .../SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml | 1 + .../Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml | 1 + .../Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml | 1 + .../SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml | 1 + .../Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml | 1 + 12 files changed, 13 insertions(+) diff --git a/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml b/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml index d8253505c42e4..54f7aa97053cb 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml @@ -21,6 +21,8 @@ <element name="coupon" type="select" selector="select[name='coupon_type']"/> <element name="couponCode" type="input" selector="input[name='coupon_code']"/> <element name="useAutoGeneration" type="checkbox" selector="input[name='use_auto_generation']"/> + <element name="fromDate" type="input" selector="input[name='from_date']"/> + <element name="toDate" type="input" selector="input[name='to_date']"/> <element name="userPerCoupon" type="input" selector="//input[@name='uses_per_coupon']"/> <element name="userPerCustomer" type="input" selector="//input[@name='uses_per_customer']"/> <element name="priority" type="input" selector="//*[@name='sort_order']"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml index c69fa97efc034..51062da6f2efe 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml @@ -40,6 +40,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Buy X get Y free (discount amount is Y)" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="1" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml index 49233cb4b42f5..44145f9290457 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml @@ -42,6 +42,7 @@ <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> <fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="{{_defaultCoupon.code}}" stepKey="fillCouponCode"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="5" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml index c1aeebfca520e..a9083cb320ccb 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml @@ -42,6 +42,7 @@ <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> <checkOption selector="{{AdminCartPriceRulesFormSection.useAutoGeneration}}" stepKey="tickAutoGeneration"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="0.99" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml index 30aa26b26ed39..9d95b01b2f81d 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml @@ -40,6 +40,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="10" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml index 7ac69f82f79da..1adf2d22be4db 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml @@ -40,6 +40,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="19.99" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml index eb04ce04f0718..42d84f13b9acf 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml @@ -40,6 +40,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Percent of product price discount" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="50" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml index ca897bffe8b79..e8b8c6cd9e683 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml @@ -43,6 +43,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml index 83854c4a767ca..ae7d0eed739ff 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml @@ -43,6 +43,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml index 60a19074317fc..c43aaf8d3c97c 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml @@ -43,6 +43,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml index f98f7b408436f..4e1944bed9b42 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml @@ -43,6 +43,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml index 6567beba198eb..8fb27a9dd1ef3 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml @@ -43,6 +43,7 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> From 778be5815ab0a55825cb25d246b61e79ea581dab Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Thu, 11 Oct 2018 14:06:43 -0500 Subject: [PATCH 269/812] MAGETWO-95259: CatalogSearch module deprecation must be reverted - Deprecated all classes/interfaces in Magento\Framework\Search\Adapter\Mysql and added missing descriptions to avoid static tests failures. - Deprecated MySQL search related unit tests (for easier removal in the future) - Removed deprecation of Magento\CatalogSearch\Model\ResourceModel\FulltextCollection (it should be kept and refactored) --- .../Model/ResourceModel/Fulltext/Collection.php | 6 +++--- .../Data/MySQLSearchDeprecationNotification.php | 6 ++++++ .../DataProvider/QueryBuilderTest.php | 2 ++ .../Mysql/Aggregation/DataProviderTest.php | 3 +++ .../Adapter/Mysql/Dynamic/DataProviderTest.php | 3 ++- .../Model/Adapter/Mysql/Field/ResolverTest.php | 3 +++ .../Adapter/Mysql/Filter/AliasResolverTest.php | 4 ++++ .../Adapter/Mysql/Filter/PreprocessorTest.php | 2 ++ .../ResourceModel/Advanced/CollectionTest.php | 2 ++ .../Unit/Model/ResourceModel/BaseCollection.php | 3 +++ .../BaseSelectStrategy/StrategyMapperTest.php | 4 ++++ .../FilterMapper/ExclusionStrategyTest.php | 2 ++ .../Search/FilterMapper/FilterContextTest.php | 4 ++++ .../FilterMapper/TermDropdownStrategyTest.php | 3 +++ .../Test/Unit/Model/Search/IndexBuilderTest.php | 2 ++ .../Test/Unit/Model/Search/TableMapperTest.php | 3 +++ .../Test/Unit/Plugin/EnableEavIndexerTest.php | 4 ++++ .../Framework/Search/Adapter/Mysql/Adapter.php | 4 ++++ .../Search/Adapter/Mysql/Aggregation/Builder.php | 14 +++++++++++--- .../Aggregation/Builder/BucketInterface.php | 6 +++++- .../Mysql/Aggregation/Builder/Container.php | 8 ++++++++ .../Mysql/Aggregation/Builder/Dynamic.php | 8 +++++++- .../Mysql/Aggregation/Builder/Metrics.php | 6 ++++++ .../Adapter/Mysql/Aggregation/Builder/Range.php | 10 +++++++++- .../Adapter/Mysql/Aggregation/Builder/Term.php | 8 +++++++- .../Mysql/Aggregation/DataProviderContainer.php | 6 ++++++ .../Mysql/Aggregation/DataProviderInterface.php | 4 +++- .../Adapter/Mysql/Aggregation/Interval.php | 14 +++++++++++--- .../Search/Adapter/Mysql/AggregationFactory.php | 3 +++ .../Search/Adapter/Mysql/ConditionManager.php | 10 ++++++++++ .../Search/Adapter/Mysql/DocumentFactory.php | 3 +++ .../Search/Adapter/Mysql/Field/Field.php | 11 +++++++++++ .../Search/Adapter/Mysql/Field/FieldFactory.php | 4 ++++ .../Adapter/Mysql/Field/FieldInterface.php | 13 +++++++++---- .../Search/Adapter/Mysql/Field/Resolver.php | 5 ++++- .../Adapter/Mysql/Field/ResolverInterface.php | 6 ++++-- .../Search/Adapter/Mysql/Filter/Builder.php | 11 ++++++++++- .../Mysql/Filter/Builder/FilterInterface.php | 6 +++++- .../Adapter/Mysql/Filter/Builder/Range.php | 16 +++++++++++++++- .../Search/Adapter/Mysql/Filter/Builder/Term.php | 10 +++++++++- .../Adapter/Mysql/Filter/Builder/Wildcard.php | 8 +++++++- .../Adapter/Mysql/Filter/BuilderInterface.php | 6 +++++- .../Search/Adapter/Mysql/Filter/Preprocessor.php | 5 ++++- .../Mysql/Filter/PreprocessorInterface.php | 6 +++++- .../Adapter/Mysql/IndexBuilderInterface.php | 3 +++ .../Framework/Search/Adapter/Mysql/Mapper.php | 11 +++++++++++ .../Search/Adapter/Mysql/Query/Builder/Match.php | 8 +++++++- .../Mysql/Query/Builder/QueryInterface.php | 6 +++++- .../Adapter/Mysql/Query/MatchContainer.php | 10 ++++++++++ .../Mysql/Query/MatchContainerFactory.php | 3 +++ .../Adapter/Mysql/Query/QueryContainer.php | 10 ++++++++++ .../Mysql/Query/QueryContainerFactory.php | 3 +++ .../Search/Adapter/Mysql/ResponseFactory.php | 3 +++ .../Search/Adapter/Mysql/ScoreBuilder.php | 2 ++ .../Search/Adapter/Mysql/ScoreBuilderFactory.php | 3 +++ .../Search/Adapter/Mysql/TemporaryStorage.php | 10 ++++++++++ .../Adapter/Mysql/TemporaryStorageFactory.php | 2 ++ 57 files changed, 309 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index 916bfdd602029..79d03b6fad2ca 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -20,12 +20,12 @@ /** * Fulltext Collection - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * + * This collection should be refactored to not have dependencies on MySQL-specific implementation. * * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection { diff --git a/app/code/Magento/CatalogSearch/Setup/Patch/Data/MySQLSearchDeprecationNotification.php b/app/code/Magento/CatalogSearch/Setup/Patch/Data/MySQLSearchDeprecationNotification.php index a58ee2bcb184d..d3c5aa5aaa6f5 100644 --- a/app/code/Magento/CatalogSearch/Setup/Patch/Data/MySQLSearchDeprecationNotification.php +++ b/app/code/Magento/CatalogSearch/Setup/Patch/Data/MySQLSearchDeprecationNotification.php @@ -7,6 +7,12 @@ namespace Magento\CatalogSearch\Setup\Patch\Data; +/** + * Implementation of the notification about MySQL search being deprecated. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class MySQLSearchDeprecationNotification implements \Magento\Framework\Setup\Patch\DataPatchInterface { /** diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilderTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilderTest.php index 72379c3819dea..949554506d5b0 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilderTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProvider/QueryBuilderTest.php @@ -20,6 +20,8 @@ * Test for Magento\CatalogSearch\Model\Adapter\Mysql\Aggregation\DataProvider\QueryBuilder. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class QueryBuilderTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProviderTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProviderTest.php index 8eeceba8209bf..85b1b136e78d2 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProviderTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Aggregation/DataProviderTest.php @@ -23,6 +23,9 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * + * @deprecated + * @see \Magento\ElasticSearch */ class DataProviderTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Dynamic/DataProviderTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Dynamic/DataProviderTest.php index 1186dd6936cc6..b064eec3338e9 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Dynamic/DataProviderTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Dynamic/DataProviderTest.php @@ -19,8 +19,9 @@ use Magento\Store\Model\StoreManager; /** - * Class DataProviderTest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class DataProviderTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Field/ResolverTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Field/ResolverTest.php index ca19e5e995c81..1e609cdeac28f 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Field/ResolverTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Field/ResolverTest.php @@ -9,6 +9,9 @@ /** * Unit tests for Magento\CatalogSearch\Model\Adapter\Mysql\Field\Resolver class. + * + * @deprecated + * @see \Magento\ElasticSearch */ class ResolverTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php index 697fab6507934..1690d9f39360f 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php @@ -9,6 +9,10 @@ use Magento\CatalogSearch\Model\Search\RequestGenerator; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +/** + * @deprecated + * @see \Magento\ElasticSearch + */ class AliasResolverTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php index 01108358da2e0..7e3de7534e8c4 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php @@ -15,6 +15,8 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class PreprocessorTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php index 21d67bdf53c56..b65a0d6ca47a0 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php @@ -13,6 +13,8 @@ * Tests Magento\CatalogSearch\Model\ResourceModel\Advanced\Collection * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class CollectionTest extends BaseCollection { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/BaseCollection.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/BaseCollection.php index e99d75c25f5cd..9ea103e23d2a7 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/BaseCollection.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/BaseCollection.php @@ -9,6 +9,9 @@ * Base class for Collection tests. * * Contains helper methods to get commonly used mocks used for collection tests. + * + * @deprecated + * @see \Magento\ElasticSearch **/ class BaseCollection extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/BaseSelectStrategy/StrategyMapperTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/BaseSelectStrategy/StrategyMapperTest.php index 5fa5b0333c6ba..b168e72811760 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/BaseSelectStrategy/StrategyMapperTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/BaseSelectStrategy/StrategyMapperTest.php @@ -11,6 +11,10 @@ use \Magento\CatalogSearch\Model\Search\BaseSelectStrategy\StrategyMapper; use \Magento\CatalogSearch\Model\Search\SelectContainer\SelectContainer; +/** + * @deprecated + * @see \Magento\ElasticSearch + */ class StrategyMapperTest extends \PHPUnit\Framework\TestCase { /** @var BaseSelectAttributesSearchStrategy|\PHPUnit_Framework_MockObject_MockObject */ diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/ExclusionStrategyTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/ExclusionStrategyTest.php index 09591532f9f06..e693807760ea5 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/ExclusionStrategyTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/ExclusionStrategyTest.php @@ -17,6 +17,8 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class ExclusionStrategyTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php index e16f23ca09d2c..12ce0d63ac685 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php @@ -16,6 +16,10 @@ use Magento\Framework\Search\Request\FilterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +/** + * @deprecated + * @see \Magento\ElasticSearch + */ class FilterContextTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/TermDropdownStrategyTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/TermDropdownStrategyTest.php index 8771c92039f4d..e064f46655d91 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/TermDropdownStrategyTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/TermDropdownStrategyTest.php @@ -18,6 +18,9 @@ /** * Class TermDropdownStrategyTest. * Unit test for \Magento\CatalogSearch\Model\Search\FilterMapper\TermDropdownStrategy. + * + * @deprecated + * @see \Magento\ElasticSearch */ class TermDropdownStrategyTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php index da7cfa1ea9821..b066c118ef783 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php @@ -27,6 +27,8 @@ * Test for \Magento\CatalogSearch\Model\Search\IndexBuilder * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class IndexBuilderTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php index cfddc07bceecc..db46755261534 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php @@ -18,7 +18,10 @@ /** * Test for \Magento\CatalogSearch\Model\Search\TableMapper + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @deprecated + * @see \Magento\ElasticSearch */ class TableMapperTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Plugin/EnableEavIndexerTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Plugin/EnableEavIndexerTest.php index 0eac2e3309aec..b20fdde7c5216 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Plugin/EnableEavIndexerTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Plugin/EnableEavIndexerTest.php @@ -9,6 +9,10 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +/** + * @deprecated + * @see \Magento\ElasticSearch + */ class EnableEavIndexerTest extends \PHPUnit\Framework\TestCase { /** diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php index 11bd746eb71e5..897b67d8d46ec 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php @@ -14,6 +14,8 @@ /** * MySQL Search Adapter * + * @deprecated + * @see \Magento\ElasticSearch * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Adapter implements AdapterInterface @@ -104,6 +106,8 @@ private function getDocuments(Table $table) } /** + * Get connection. + * * @return false|\Magento\Framework\DB\Adapter\AdapterInterface */ private function getConnection() diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder.php index 47d991274b9e0..4a5802dd44e04 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder.php @@ -15,6 +15,10 @@ use Magento\Framework\Search\RequestInterface; /** + * MySQL search aggregation builder. + * + * @deprecated + * @see \Magento\ElasticSearch * @api */ class Builder @@ -66,6 +70,8 @@ public function __construct( } /** + * Build aggregations. + * * @param RequestInterface $request * @param Table $documentsTable * @param array $documents @@ -77,6 +83,8 @@ public function build(RequestInterface $request, Table $documentsTable, array $d } /** + * Process aggregations. + * * @param RequestInterface $request * @param Table $documentsTable * @param array $documents @@ -102,7 +110,7 @@ private function processAggregations(RequestInterface $request, Table $documents } /** - * Extract document ids + * Extract document ids. * * @param array $documents * @return array @@ -113,7 +121,7 @@ private function extractDocumentIds(array $documents) } /** - * Get document ids + * Get document ids. * * @param Table $documentsTable * @return array @@ -128,7 +136,7 @@ private function getDocumentIds(Table $documentsTable) } /** - * Get Connection + * Get Connection. * * @return AdapterInterface */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/BucketInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/BucketInterface.php index 90220676e0068..4fa2474d2258e 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/BucketInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/BucketInterface.php @@ -11,12 +11,16 @@ use Magento\Framework\Search\Request\Dimension; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Aggregation\Builder\BucketInterface + * MySQL search aggregation bucket builder. * + * @deprecated + * @see \Magento\ElasticSearch */ interface BucketInterface { /** + * Build bucket. + * * @param DataProviderInterface $dataProvider * @param Dimension[] $dimensions * @param RequestBucketInterface $bucket diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Container.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Container.php index cba29ad6287d3..844cfc9f8741d 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Container.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Container.php @@ -5,6 +5,12 @@ */ namespace Magento\Framework\Search\Adapter\Mysql\Aggregation\Builder; +/** + * MySQL search aggregation container builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Container { /** @@ -21,6 +27,8 @@ public function __construct(array $buckets) } /** + * Get bucket by type. + * * @param string $bucketType * @return BucketInterface */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Dynamic.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Dynamic.php index 481b2252dbf69..46828ab7a8c73 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Dynamic.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Dynamic.php @@ -12,6 +12,12 @@ use Magento\Framework\Search\Request\Aggregation\DynamicBucket; use Magento\Framework\Search\Request\BucketInterface as RequestBucketInterface; +/** + * MySQL search dynamic aggregation builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Dynamic implements BucketInterface { /** @@ -37,7 +43,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function build( DataProviderInterface $dataProvider, diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php index 840f94622183a..e4cdb04052ef2 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php @@ -7,6 +7,12 @@ use Magento\Framework\Search\Request\BucketInterface as RequestBucketInterface; +/** + * MySQL search aggregation metrics builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Metrics { /** diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Range.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Range.php index 29fc6806b50e7..aced57c100130 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Range.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Range.php @@ -14,6 +14,12 @@ use Magento\Framework\Search\Request\BucketInterface as RequestBucketInterface; use Magento\Framework\Translate\AdapterInterface; +/** + * MySQL search aggregation range builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Range implements BucketInterface { const GREATER_THAN = '>='; @@ -46,7 +52,7 @@ public function __construct(Metrics $metricsBuilder, ResourceConnection $resourc } /** - * {@inheritdoc} + * @inheritdoc */ public function build( DataProviderInterface $dataProvider, @@ -70,6 +76,8 @@ public function build( } /** + * Generate case. + * * @param Select $select * @param AggregationRange[] $ranges * @return Select diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Term.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Term.php index 78ff7b04fd39c..547526be43ccd 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Term.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Term.php @@ -9,6 +9,12 @@ use Magento\Framework\Search\Adapter\Mysql\Aggregation\DataProviderInterface; use Magento\Framework\Search\Request\BucketInterface as RequestBucketInterface; +/** + * MySQL search aggregation term builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Term implements BucketInterface { /** @@ -25,7 +31,7 @@ public function __construct(Metrics $metricsBuilder) } /** - * {@inheritdoc} + * @inheritdoc */ public function build( DataProviderInterface $dataProvider, diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderContainer.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderContainer.php index 6a817bcbddf82..565b5eeef3351 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderContainer.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderContainer.php @@ -6,6 +6,10 @@ namespace Magento\Framework\Search\Adapter\Mysql\Aggregation; /** + * MySQL search data provider container. + * + * @deprecated + * @see \Magento\ElasticSearch * @api */ class DataProviderContainer @@ -24,6 +28,8 @@ public function __construct(array $dataProviders) } /** + * Get data provider by index name. + * * @param string $indexName * @return DataProviderInterface */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderInterface.php index b18269335bc6f..c251265c694d2 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/DataProviderInterface.php @@ -11,8 +11,10 @@ use Magento\Framework\Search\Request\Dimension; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Aggregation\DataProviderInterface + * MySQL search data provider. * + * @deprecated + * @see \Magento\ElasticSearch */ interface DataProviderInterface { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Interval.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Interval.php index ed5640d42274f..ba41a535f45c9 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Interval.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Interval.php @@ -8,6 +8,12 @@ use Magento\Framework\DB\Select; use Magento\Framework\Search\Dynamic\IntervalInterface; +/** + * MySQL search aggregation interval. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Interval implements IntervalInterface { /** @@ -41,7 +47,7 @@ private function getValueFiled() } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function load($limit, $offset = null, $lower = null, $upper = null) @@ -64,7 +70,7 @@ public function load($limit, $offset = null, $lower = null, $upper = null) } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function loadPrevious($data, $index, $lower = null) @@ -86,7 +92,7 @@ public function loadPrevious($data, $index, $lower = null) } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function loadNext($data, $rightIndex, $upper = null) @@ -124,6 +130,8 @@ public function loadNext($data, $rightIndex, $upper = null) } /** + * Convert array values to float. + * * @param array $prices * @return array */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/AggregationFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/AggregationFactory.php index 4d255705bf7df..756d9edc6fbe1 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/AggregationFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/AggregationFactory.php @@ -7,6 +7,9 @@ /** * Aggregation Factory + * + * @deprecated + * @see \Magento\ElasticSearch */ class AggregationFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php index 41d6b14b6a477..413af71814198 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php @@ -9,7 +9,11 @@ use Magento\Framework\DB\Adapter\AdapterInterface; /** + * MySQL search condition manager + * * @api + * @deprecated + * @see \Magento\ElasticSearch */ class ConditionManager { @@ -30,6 +34,8 @@ public function __construct(ResourceConnection $resource) } /** + * Wrap query with parentheces. + * * @param string $query * @return string */ @@ -41,6 +47,8 @@ public function wrapBrackets($query) } /** + * Combine multiple queries. + * * @param string[] $queries * @param string $unionOperator * @return string @@ -54,6 +62,8 @@ public function combineQueries(array $queries, $unionOperator) } /** + * Generate query condition. + * * @param string $field * @param string $operator * @param mixed $value diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/DocumentFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/DocumentFactory.php index 3ca0e94852a5e..4e8854fad353a 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/DocumentFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/DocumentFactory.php @@ -13,7 +13,10 @@ /** * Document Factory + * * @api + * @deprecated + * @see \Magento\ElasticSearch */ class DocumentFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Field.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Field.php index 72495e68a26ff..0a340e7f76dc0 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Field.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Field.php @@ -6,6 +6,11 @@ namespace Magento\Framework\Search\Adapter\Mysql\Field; +/** + * @inheritdoc + * @deprecated + * @see \Magento\ElasticSearch + */ class Field implements FieldInterface { /** @@ -36,6 +41,8 @@ public function __construct($column, $attributeId = null, $type = self::TYPE_FUL } /** + * Get column. + * * @return string */ public function getColumn() @@ -44,6 +51,8 @@ public function getColumn() } /** + * Get attribute ID. + * * @return int|null */ public function getAttributeId() @@ -52,6 +61,8 @@ public function getAttributeId() } /** + * Get type. + * * @return int */ public function getType() diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldFactory.php index 9a3c55965740e..066d1832aefbf 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldFactory.php @@ -7,7 +7,11 @@ namespace Magento\Framework\Search\Adapter\Mysql\Field; /** + * MySQL search field factory. + * * @api + * @deprecated + * @see \Magento\ElasticSearch */ class FieldFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldInterface.php index 5f4e0027a8508..7dc74f39709f9 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/FieldInterface.php @@ -7,8 +7,10 @@ namespace Magento\Framework\Search\Adapter\Mysql\Field; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Field\FieldInterface + * MySQL search field. * + * @deprecated + * @see \Magento\ElasticSearch */ interface FieldInterface { @@ -16,19 +18,22 @@ interface FieldInterface const TYPE_FULLTEXT = 2; /** - * Get type of index + * Get type of index. + * * @return int */ public function getType(); /** - * Get ID of attribute + * Get ID of attribute. + * * @return int */ public function getAttributeId(); /** - * Get field name + * Get field nam. + * * @return string */ public function getColumn(); diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Resolver.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Resolver.php index 5146177783ae2..908d6ccc50746 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Resolver.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/Resolver.php @@ -5,6 +5,9 @@ */ namespace Magento\Framework\Search\Adapter\Mysql\Field; +/** + * @inheritdoc + */ class Resolver implements ResolverInterface { /** @@ -21,7 +24,7 @@ public function __construct(FieldFactory $fieldFactory) } /** - * {@inheritdoc} + * @inheritdoc */ public function resolve(array $fields) { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/ResolverInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/ResolverInterface.php index f275c4f1b1c14..5455b91d73020 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/ResolverInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Field/ResolverInterface.php @@ -6,13 +6,15 @@ namespace Magento\Framework\Search\Adapter\Mysql\Field; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Field\ResolverInterface + * MySQL search field resolver. * + * @deprecated + * @see \Magento\ElasticSearch */ interface ResolverInterface { /** - * Resolve field + * Resolve field. * * @param array $fields * @return FieldInterface[] diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder.php index 80074ffc5e2b9..ce02bef244fbb 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder.php @@ -15,6 +15,7 @@ use Magento\Framework\Search\Request\Query\BoolExpression; /** + * @inheritdoc * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Builder implements BuilderInterface @@ -58,7 +59,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function build(RequestFilterInterface $filter, $conditionType) { @@ -66,6 +67,8 @@ public function build(RequestFilterInterface $filter, $conditionType) } /** + * Process filter. + * * @param RequestFilterInterface $filter * @param bool $isNegation * @return string @@ -87,6 +90,8 @@ private function processFilter(RequestFilterInterface $filter, $isNegation) } /** + * Process boolean filter. + * * @param RequestFilterInterface|\Magento\Framework\Search\Request\Filter\Bool $filter * @param bool $isNegation * @return string @@ -111,6 +116,8 @@ private function processBoolFilter(RequestFilterInterface $filter, $isNegation) } /** + * Build filters. + * * @param \Magento\Framework\Search\Request\FilterInterface[] $filters * @param string $unionOperator * @param bool $isNegation @@ -127,6 +134,8 @@ private function buildFilters(array $filters, $unionOperator, $isNegation) } /** + * Check if condition type is 'negative'. + * * @param string $conditionType * @return bool */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/FilterInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/FilterInterface.php index 787866a2bca38..6f8b63955a0c1 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/FilterInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/FilterInterface.php @@ -8,12 +8,16 @@ use Magento\Framework\Search\Request\FilterInterface as RequestFilterInterface; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Filter\Builder\FilterInterface + * MySQL search filter builder. * + * @deprecated + * @see \Magento\ElasticSearch */ interface FilterInterface { /** + * Build filter. + * * @param RequestFilterInterface $filter * @param bool $isNegation * @return string diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Range.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Range.php index d4ee9542c5934..d14bfdcb548d3 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Range.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Range.php @@ -9,6 +9,12 @@ use Magento\Framework\Search\Request\Filter\Range as RangeFilterRequest; use Magento\Framework\Search\Request\FilterInterface as RequestFilterInterface; +/** + * Range filter builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Range implements FilterInterface { const CONDITION_PART_GREATER_THAN = '>='; @@ -31,7 +37,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function buildFilter( RequestFilterInterface $filter, @@ -48,6 +54,8 @@ public function buildFilter( } /** + * Get left condition filter part. + * * @param RequestFilterInterface|RangeFilterRequest $filter * @param bool $isNegation * @return string @@ -62,6 +70,8 @@ private function getLeftConditionPart(RequestFilterInterface $filter, $isNegatio } /** + * Get right condition filter part. + * * @param RequestFilterInterface|RangeFilterRequest $filter * @param bool $isNegation * @return string @@ -76,6 +86,8 @@ private function getRightConditionPart(RequestFilterInterface $filter, $isNegati } /** + * Get filter part. + * * @param string $field * @param string $operator * @param string $value @@ -89,6 +101,8 @@ private function getPart($field, $operator, $value) } /** + * Get condition union operator. + * * @param bool $isNegation * @return string */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Term.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Term.php index 3ac755de2b8a3..c89ef50f3cb35 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Term.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Term.php @@ -8,6 +8,12 @@ use Magento\Framework\Search\Adapter\Mysql\ConditionManager; use Magento\Framework\Search\Request\FilterInterface as RequestFilterInterface; +/** + * Term filter builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Term implements FilterInterface { const CONDITION_OPERATOR_EQUALS = '='; @@ -30,7 +36,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function buildFilter( RequestFilterInterface $filter, @@ -46,6 +52,8 @@ public function buildFilter( } /** + * Get condition operator. + * * @param string|array $value * @param bool $isNegation * @return string diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Wildcard.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Wildcard.php index 308d1d564301d..9a2776ac20b2c 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Wildcard.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Builder/Wildcard.php @@ -7,6 +7,12 @@ use Magento\Framework\Search\Adapter\Mysql\ConditionManager; +/** + * Wildcard filter builder. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class Wildcard implements FilterInterface { const CONDITION_LIKE = 'LIKE'; @@ -27,7 +33,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function buildFilter( \Magento\Framework\Search\Request\FilterInterface $filter, diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderInterface.php index ec3b88ad24507..3da989333d668 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/BuilderInterface.php @@ -8,12 +8,16 @@ use Magento\Framework\Search\Request\FilterInterface as RequestFilterInterface; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Filter\BuilderInterface + * MySQL search filter builder. * + * @deprecated + * @see \Magento\ElasticSearch */ interface BuilderInterface { /** + * Buil filter. + * * @param RequestFilterInterface $filter * @param string $conditionType * @return string diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Preprocessor.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Preprocessor.php index a8bb8e255f2cb..32d134cfe8d6d 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Preprocessor.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/Preprocessor.php @@ -8,6 +8,9 @@ use Magento\Framework\Search\Adapter\Mysql\ConditionManager; use Magento\Framework\Search\Request\FilterInterface; +/** + * @inheritdoc + */ class Preprocessor implements PreprocessorInterface { /** @@ -24,7 +27,7 @@ public function __construct(ConditionManager $conditionManager) } /** - * {@inheritdoc} + * @inheritdoc */ public function process(FilterInterface $filter, $isNegation, $query) { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/PreprocessorInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/PreprocessorInterface.php index 430b775337b7f..eb0bbc6f3b563 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/PreprocessorInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Filter/PreprocessorInterface.php @@ -8,12 +8,16 @@ use Magento\Framework\Search\Request\FilterInterface; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Filter\PreprocessorInterface + * MySQL search filter pre-processor. * + * @deprecated + * @see \Magento\ElasticSearch */ interface PreprocessorInterface { /** + * Process filter. + * * @param FilterInterface $filter * @param bool $isNegation * @param string $query diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/IndexBuilderInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/IndexBuilderInterface.php index 73c20406f35df..fbd35455c2294 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/IndexBuilderInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/IndexBuilderInterface.php @@ -10,6 +10,9 @@ /** * Build base Query for Index + * + * @deprecated + * @see \Magento\ElasticSearch */ interface IndexBuilderInterface { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php index fb4ff5d298c12..e97a6690dbcc2 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php @@ -22,8 +22,11 @@ /** * Mapper class. Maps library request to specific adapter dependent query + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api + * @deprecated + * @see \Magento\ElasticSearch */ class Mapper { @@ -344,6 +347,8 @@ private function processFilterQuery( } /** + * Add match queries to select. + * * @param RequestInterface $request * @param QueryContainer $queryContainer * @param ScoreBuilder $scoreBuilder @@ -380,6 +385,8 @@ private function addDerivedQueries( } /** + * Get connection. + * * @return false|\Magento\Framework\DB\Adapter\AdapterInterface */ private function getConnection() @@ -388,6 +395,8 @@ private function getConnection() } /** + * Add match queries to select. + * * @param RequestInterface $request * @param Select $select * @param IndexBuilderInterface $indexBuilder @@ -424,6 +433,8 @@ private function addMatchQueries( } /** + * Join previous result to select. + * * @param Select $query * @param Table $previousResultTable * @param ScoreBuilder $scoreBuilder diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php index 8e3758817adf0..fb44e4037bcf7 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/Match.php @@ -15,7 +15,11 @@ use Magento\Framework\Search\Adapter\Preprocessor\PreprocessorInterface; /** + * MySQL search query match. + * * @api + * @deprecated + * @see \Magento\ElasticSearch */ class Match implements QueryInterface { @@ -69,7 +73,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function build( ScoreBuilder $scoreBuilder, @@ -113,6 +117,8 @@ public function build( } /** + * Prepare query. + * * @param string $queryValue * @param string $conditionType * @return string diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/QueryInterface.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/QueryInterface.php index a2446264d48d7..6796a1f995e4f 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/QueryInterface.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/Builder/QueryInterface.php @@ -8,12 +8,16 @@ use Magento\Framework\Search\Adapter\Mysql\ScoreBuilder; /** - * Interface \Magento\Framework\Search\Adapter\Mysql\Query\Builder\QueryInterface + * MySQL search query builder. * + * @deprecated + * @see \Magento\ElasticSearch */ interface QueryInterface { /** + * Build query. + * * @param \Magento\Framework\Search\Adapter\Mysql\ScoreBuilder $scoreBuilder * @param \Magento\Framework\DB\Select $select * @param \Magento\Framework\Search\Request\QueryInterface $query diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainer.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainer.php index b694cd48a07af..6ed3338c040e2 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainer.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainer.php @@ -10,6 +10,12 @@ // @codeCoverageIgnore +/** + * MySQL search query match container. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class MatchContainer { /** @@ -34,6 +40,8 @@ public function __construct(QueryInterface $request, $conditionType) } /** + * Get request. + * * @return QueryInterface */ public function getRequest() @@ -42,6 +50,8 @@ public function getRequest() } /** + * Get condition type. + * * @return string */ public function getConditionType() diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainerFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainerFactory.php index ba103e060ae7c..cb10de7bdcbbc 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainerFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/MatchContainerFactory.php @@ -7,6 +7,9 @@ /** * MatchContainer Factory + * + * @deprecated + * @see \Magento\ElasticSearch */ class MatchContainerFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainer.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainer.php index be8507838e44f..9161a30f9bc51 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainer.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainer.php @@ -9,6 +9,12 @@ use Magento\Framework\DB\Select; use Magento\Framework\Search\Request\QueryInterface as RequestQueryInterface; +/** + * MySQL search query container. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class QueryContainer { const DERIVED_QUERY_PREFIX = 'derived_'; @@ -32,6 +38,8 @@ public function __construct(MatchContainerFactory $matchContainerFactory) } /** + * Add query to select. + * * @param Select $select * @param RequestQueryInterface $query * @param string $conditionType @@ -54,6 +62,8 @@ public function addMatchQuery( } /** + * Get queries. + * * @return MatchContainer[] */ public function getMatchQueries() diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainerFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainerFactory.php index 70fefec13dd88..59ee4bb045b2a 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainerFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Query/QueryContainerFactory.php @@ -7,6 +7,9 @@ /** * MatchContainer Factory + * + * @deprecated + * @see \Magento\ElasticSearch */ class QueryContainerFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php index 8a269d8d95bc2..776dab93c2dcd 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php @@ -7,6 +7,9 @@ /** * Response Factory + * + * @deprecated + * @see \Magento\ElasticSearch */ class ResponseFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilder.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilder.php index 190d3a04ed210..1cc417f891c19 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilder.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilder.php @@ -9,6 +9,8 @@ * Class for generating sql condition for calculating store manager * * @api + * @deprecated + * @see \Magento\ElasticSearch */ class ScoreBuilder { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilderFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilderFactory.php index 4a7612fcc3042..70aa749fd859f 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilderFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ScoreBuilderFactory.php @@ -7,6 +7,9 @@ /** * ScoreBuilder Factory + * + * @deprecated + * @see \Magento\ElasticSearch */ class ScoreBuilderFactory { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorage.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorage.php index dcb977bfa2ae8..60ee2d5706067 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorage.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorage.php @@ -13,7 +13,11 @@ use Magento\Framework\DB\Select; /** + * MySQL search temporary storage. + * * @api + * @deprecated + * @see \Magento\ElasticSearch */ class TemporaryStorage { @@ -100,6 +104,8 @@ private function populateTemporaryTable(Table $table, $data) } /** + * Store select results in temporary table. + * * @param Select $select * @return Table * @throws \Zend_Db_Exception @@ -112,6 +118,8 @@ public function storeDocumentsFromSelect(Select $select) } /** + * Get connection. + * * @return false|AdapterInterface */ private function getConnection() @@ -120,6 +128,8 @@ private function getConnection() } /** + * Create temporary table for search select results. + * * @return Table * @throws \Zend_Db_Exception */ diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorageFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorageFactory.php index 4a282faf317ce..208f6b39b9eb4 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorageFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorageFactory.php @@ -12,6 +12,8 @@ * * @codeCoverageIgnore * @api + * @deprecated + * @see \Magento\ElasticSearch */ class TemporaryStorageFactory { From 58c13d6ffab80a2fcca35b151d60f2ca6577c80a Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 11 Oct 2018 14:43:45 -0500 Subject: [PATCH 270/812] MAGETWO-95483: Can't delete a cart entry when the cart has a shipping address - Added test assertion for bugfix --- .../Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php | 9 ++++----- .../Plugin/Model/Quote/ResetQuoteAddressesTest.php | 6 ++++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php b/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php index a63072f5a3de7..4f05279350a7c 100644 --- a/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php +++ b/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php @@ -27,11 +27,10 @@ public function afterRemoveItem(Quote $quote, Quote $result, $itemId): Quote if (empty($result->getAllVisibleItems())) { foreach ($result->getAllAddresses() as $address) { $result->removeAddress($address->getId()); - - $extensionAttributes = $result->getExtensionAttributes(); - if (!$result->isVirtual() && $extensionAttributes && $extensionAttributes->getShippingAssignments()) { - $extensionAttributes->setShippingAssignments([]); - } + } + $extensionAttributes = $result->getExtensionAttributes(); + if (!$result->isVirtual() && $extensionAttributes && $extensionAttributes->getShippingAssignments()) { + $extensionAttributes->setShippingAssignments([]); } } diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php index e533dbfa0c879..994076badddae 100644 --- a/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php +++ b/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php @@ -52,9 +52,15 @@ public function testAfterRemoveItem(): void $cart = Bootstrap::getObjectManager()->create(Cart::class); $activeQuote = $cart->getQuote(); + // Dummy data is still persisted here. This is sufficient to check that it is removed + $activeQuote->getExtensionAttributes()->setShippingAssignments(['test']); + $cart->removeItem($activeQuote->getAllVisibleItems()[0]->getId()); $cart->save(); + // Check that the shipping assignments were also unset + $this->assertEmpty($activeQuote->getExtensionAttributes()->getShippingAssignments()); + /** @var Quote $quote */ $quote = Bootstrap::getObjectManager()->create(Quote::class); $quote->load('test_order_with_virtual_product', 'reserved_order_id'); From 8574dac6e8eaef7cb0b0da7f0aca347d3e82fe02 Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Thu, 11 Oct 2018 15:23:32 -0500 Subject: [PATCH 271/812] MQE-1303: AdminCreateCustomerTestCest test sequence failure --- .../Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml index 9dd2127fa28b2..6bde63d900c17 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml @@ -27,17 +27,17 @@ <amOnPage url="{{AdminCustomerPage.url}}" stepKey="navigateToCustomers"/> <waitForPageLoad stepKey="waitForLoad1"/> <click selector="{{AdminCustomerGridMainActionsSection.addNewCustomer}}" stepKey="clickCreateCustomer"/> - <waitForElement selector="{{AdminCustomerAccountInformationSection.firstName}}" stepKey="wait1"/> <fillField userInput="{{CustomerEntityOne.firstname}}" selector="{{AdminCustomerAccountInformationSection.firstName}}" stepKey="fillFirstName"/> <fillField userInput="{{CustomerEntityOne.lastname}}" selector="{{AdminCustomerAccountInformationSection.lastName}}" stepKey="fillLastName"/> <fillField userInput="{{CustomerEntityOne.email}}" selector="{{AdminCustomerAccountInformationSection.email}}" stepKey="fillEmail"/> <click selector="{{AdminCustomerMainActionsSection.saveButton}}" stepKey="saveCustomer"/> - <waitForElementNotVisible selector="div [data-role='spinner']" time="10" stepKey="waitForSpinner1"/> <seeElement selector="{{AdminCustomerMessagesSection.successMessage}}" stepKey="assertSuccessMessage"/> + <magentoCLI stepKey="reindex" command="indexer:reindex"/> + <reloadPage stepKey="reloadPage"/> + <waitForPageLoad stepKey="waitForLoad2"/> <click selector="{{AdminCustomerFiltersSection.filtersButton}}" stepKey="openFilter"/> <fillField userInput="{{CustomerEntityOne.email}}" selector="{{AdminCustomerFiltersSection.emailInput}}" stepKey="filterEmail"/> <click selector="{{AdminCustomerFiltersSection.apply}}" stepKey="applyFilter"/> - <waitForElementNotVisible selector="div [data-role='spinner']" time="10" stepKey="waitForSpinner2"/> <see userInput="{{CustomerEntityOne.firstname}}" selector="{{AdminCustomerGridSection.customerGrid}}" stepKey="assertFirstName"/> <see userInput="{{CustomerEntityOne.lastname}}" selector="{{AdminCustomerGridSection.customerGrid}}" stepKey="assertLastName"/> <see userInput="{{CustomerEntityOne.email}}" selector="{{AdminCustomerGridSection.customerGrid}}" stepKey="assertEmail"/> From 8ee82302d4ee9964abb8c867c5f72ca4c3969356 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Thu, 11 Oct 2018 16:01:35 -0500 Subject: [PATCH 272/812] MAGETWO-95238: Cannot reset customer password from Admin Panel - fix static test failure --- .../Customer/Controller/Adminhtml/Index/ResetPassword.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php index 69af6f4fb1b27..3e6046b0d117f 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php @@ -9,6 +9,11 @@ use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\SecurityViolationException; +/** + * Reset password controller + * + * @package Magento\Customer\Controller\Adminhtml\Index + */ class ResetPassword extends \Magento\Customer\Controller\Adminhtml\Index implements HttpGetActionInterface { /** From df29676e93e1345c933927d81dbb7b80d4b25788 Mon Sep 17 00:00:00 2001 From: duhon <duhon@rambler.ru> Date: Fri, 12 Oct 2018 11:34:44 +0300 Subject: [PATCH 273/812] MAGETWO-95652: Call to \Magento\Framework\Api\MetadataServiceInterface::getCustomAttributesMetadata leads to fatal error --- app/code/Magento/Catalog/Model/Product.php | 66 +++++++++++++++------- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index 5a00f8bfbee8a..a488e306473b2 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -498,8 +498,9 @@ protected function _getResource() } /** - * Get a list of custom attribute codes that belongs to product attribute set. If attribute set not specified for - * product will return all product attribute codes + * Get a list of custom attribute codes that belongs to product attribute set. + * + * If attribute set not specified fors product will return all product attribute codes * * @return string[] */ @@ -514,7 +515,8 @@ protected function getCustomAttributesCodes() $this ) ) - ), ProductInterface::ATTRIBUTES + ), + ProductInterface::ATTRIBUTES ); } @@ -587,8 +589,9 @@ public function getPrice() } /** - * @codeCoverageIgnoreStart * Get visibility status + * + * @codeCoverageIgnoreStart * @see \Magento\Catalog\Model\Product\Visibility * * @return int @@ -665,6 +668,7 @@ public function getStatus() /** * Retrieve type instance of the product. + * * Type instance implements product type depended logic and is a singleton shared by all products of the same type. * * @return \Magento\Catalog\Model\Product\Type\AbstractType @@ -825,9 +829,10 @@ public function getStoreIds() /** * Retrieve product attributes - * if $groupId is null - retrieve all product attributes * - * @param int $groupId Retrieve attributes of the specified group + * If $groupId is null - retrieve all product attributes + * + * @param int $groupId Retrieve attributes of the specified group * @param bool $skipSuper Not used * @return \Magento\Eav\Model\Entity\Attribute\AbstractAttribute[] * @SuppressWarnings(PHPMD.UnusedFormalParameter) @@ -919,6 +924,7 @@ public function beforeSave() /** * Check/set if options can be affected when saving product + * * If value specified, it will be set. * * @param bool $value @@ -1039,9 +1045,11 @@ public function reindex() /** * Clear cache related with product and protect delete from not admin + * * Register indexing event before delete product * * @return \Magento\Catalog\Model\Product + * @throws \Magento\Framework\Exception\LocalizedException */ public function beforeDelete() { @@ -1548,12 +1556,12 @@ public function hasGalleryAttribute() /** * Add image to media gallery * - * @param string $file file path of image in file system - * @param string|array $mediaAttribute code of attribute with type 'media_image', - * leave blank if image should be only in gallery - * @param boolean $move if true, it will move source file - * @param boolean $exclude mark image as disabled in product page view + * @param string $file file path of image in file system + * @param string|array $mediaAttribute code of type 'media_image', leave blank if image should be only in gallery + * @param boolean $move if true, it will move source file + * @param boolean $exclude mark image as disabled in product page view * @return \Magento\Catalog\Model\Product + * @throws \Magento\Framework\Exception\LocalizedException */ public function addImageToMediaGallery($file, $mediaAttribute = null, $move = false, $exclude = true) { @@ -1714,7 +1722,6 @@ public function getIsSalable() /** * Check is a virtual product - * Data helper wrapper * * @return bool */ @@ -1807,8 +1814,8 @@ public function formatUrlKey($str) * Save current attribute with code $code and assign new value * * @param string $code Attribute code - * @param mixed $value New attribute value - * @param int $store Store ID + * @param mixed $value New attribute value + * @param int $store Store ID * @return void */ public function addAttributeUpdate($code, $value, $store) @@ -1878,6 +1885,7 @@ public function getRequestPath() /** * Custom function for other modules + * * @return string */ public function getGiftMessageAvailable() @@ -1996,6 +2004,8 @@ public function getOptions() } /** + * Set options for product + * * @param \Magento\Catalog\Api\Data\ProductCustomOptionInterface[] $options * @return $this */ @@ -2019,10 +2029,10 @@ public function getIsVirtual() /** * Add custom option information to product * - * @param string $code Option code - * @param mixed $value Value of the option - * @param int|Product $product Product ID - * @return $this + * @param string $code Option code + * @param mixed $value Value of the option + * @param int|Product $product Product ID + * @return $this */ public function addCustomOption($code, $value, $product = null) { @@ -2216,6 +2226,7 @@ public function getPreconfiguredValues() /** * Prepare product custom options. + * * To be sure that all product custom options does not has ID and has product instance * * @return \Magento\Catalog\Model\Product @@ -2550,9 +2561,9 @@ public function setTypeId($typeId) } /** - * {@inheritdoc} + * Retrieve existing extension attributes object or create a new one. * - * @return \Magento\Catalog\Api\Data\ProductExtensionInterface + * @return \Magento\Framework\Api\ExtensionAttributesInterface */ public function getExtensionAttributes() { @@ -2560,7 +2571,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} + * Set an extension attributes object. * * @param \Magento\Catalog\Api\Data\ProductExtensionInterface $extensionAttributes * @return $this @@ -2573,8 +2584,11 @@ public function setExtensionAttributes(\Magento\Catalog\Api\Data\ProductExtensio //@codeCoverageIgnoreEnd /** + * Convert to media gallery interface + * * @param array $mediaGallery * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[] + * @throws \Magento\Framework\Exception\LocalizedException */ protected function convertToMediaGalleryInterface(array $mediaGallery) { @@ -2590,7 +2604,10 @@ protected function convertToMediaGalleryInterface(array $mediaGallery) } /** + * Get media gallery entries + * * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface[]|null + * @throws \Magento\Framework\Exception\LocalizedException */ public function getMediaGalleryEntries() { @@ -2604,8 +2621,11 @@ public function getMediaGalleryEntries() } /** + * Set media gallery entries + * * @param ProductAttributeMediaGalleryEntryInterface[] $mediaGalleryEntries * @return $this + * @throws \Magento\Framework\Exception\LocalizedException */ public function setMediaGalleryEntries(array $mediaGalleryEntries = null) { @@ -2646,6 +2666,8 @@ public function setId($value) } /** + * Get link repository + * * @return ProductLinkRepositoryInterface */ private function getLinkRepository() @@ -2658,6 +2680,8 @@ private function getLinkRepository() } /** + * Get media gallery processor + * * @return Product\Gallery\Processor */ private function getMediaGalleryProcessor() From 596ffb10ba2dc95f012cc39693ff513a2b41889c Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Wed, 19 Sep 2018 09:10:37 +0300 Subject: [PATCH 274/812] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch --- .../CategoryFieldsProvider.php | 43 +- .../Adapter/DataMapper/ProductDataMapper.php | 53 ++- .../FieldProvider/FieldIndex/Converter.php | 36 ++ .../FieldIndex/IndexResolver.php | 86 ++++ .../FieldProvider/FieldType/Converter.php | 45 +++ .../FieldType/Resolver/CompositeResolver.php | 45 +++ .../FieldType/Resolver/IntegerType.php | 52 +++ .../FieldType/Resolver/KeywordType.php | 44 ++ .../FieldMapper/ProductFieldMapper.php | 186 +++------ .../Model/Adapter/FieldType.php | 12 + .../CategoryFieldsProvider.php | 43 +- .../BatchDataMapper/PriceFieldsProvider.php | 38 +- .../Model/Adapter/Elasticsearch.php | 25 +- .../FieldMapper/Product/AttributeAdapter.php | 177 +++++++++ .../AttributeAdapter/DummyAttribute.php | 14 + .../FieldMapper/Product/AttributeProvider.php | 77 ++++ .../Product/CompositeFieldProvider.php | 39 ++ .../FieldName/Resolver/NotEavAttribute.php | 45 --- .../Product/FieldName/Resolver/Price.php | 49 --- .../Product/FieldName/Resolver/Resolver.php | 54 --- .../FieldName/Resolver/SpecialAttribute.php | 27 -- .../Product/FieldName/ResolverInterface.php | 39 -- .../Product/FieldProvider/DynamicField.php | 134 +++++++ .../FieldProvider/FieldIndex/Converter.php | 34 ++ .../FieldIndex/ConverterInterface.php | 26 ++ .../FieldIndex/IndexResolver.php | 43 ++ .../FieldIndex/ResolverInterface.php | 23 ++ .../FieldName/Resolver/CategoryName.php | 30 +- .../FieldName/Resolver/CompositeResolver.php | 45 +++ .../FieldName/Resolver/DefaultResolver.php | 62 +-- .../FieldName/Resolver/NotEavAttribute.php | 28 ++ .../FieldName/Resolver/Position.php | 28 +- .../FieldName/Resolver/Price.php | 57 +++ .../FieldName/Resolver/SpecialAttribute.php | 28 ++ .../FieldName/ResolverInterface.php | 24 ++ .../FieldProvider/FieldType/Converter.php | 42 ++ .../FieldType/ConverterInterface.php | 31 ++ .../FieldType/Resolver/CompositeResolver.php | 45 +++ .../FieldType/Resolver/DateTimeType.php | 42 ++ .../FieldType/Resolver/DefaultResolver.php | 38 ++ .../FieldType/Resolver/FloatType.php | 42 ++ .../FieldType/Resolver/IntegerType.php | 44 ++ .../FieldType/ResolverInterface.php | 23 ++ .../Product/FieldProvider/StaticField.php | 112 ++++++ .../Product/FieldProviderInterface.php | 21 + .../FieldMapper/ProductFieldMapper.php | 40 -- .../Elasticsearch/Model/Adapter/FieldType.php | 13 +- .../FieldIndex/IndexResolverTest.php | 161 ++++++++ .../FieldType/Resolver/IntegerTypeTest.php | 99 +++++ .../FieldType/Resolver/KeywordTypeTest.php | 99 +++++ .../FieldMapper/ProductFieldMapperTest.php | 296 -------------- .../Model/Adapter/FieldTypeTest.php | 107 ----- .../Product/AttributeAdapterTest.php | 375 ++++++++++++++++++ .../FieldProvider/DynamicFieldTest.php | 327 +++++++++++++++ .../FieldIndex/IndexResolverTest.php | 95 +++++ .../FieldName/Resolver/CategoryNameTest.php | 119 ++++++ .../Resolver/DefaultResolverTest.php | 113 ++++++ .../Resolver/NotEavAttributeTest.php | 74 ++++ .../FieldName/Resolver/PositionTest.php | 119 ++++++ .../FieldName/Resolver/PriceTest.php | 107 +++++ .../Resolver/SpecialAttributeTest.php | 68 ++++ .../FieldProvider/FieldType/ConverterTest.php | 70 ++++ .../FieldType/Resolver/DateTimeTypeTest.php | 83 ++++ .../Resolver/DefaultResolverTest.php | 77 ++++ .../FieldType/Resolver/FloatTypeTest.php | 83 ++++ .../FieldType/Resolver/IntegerTypeTest.php | 99 +++++ .../Product/FieldProvider/StaticFieldTest.php | 245 ++++++++++++ .../FieldMapper/ProductFieldMapperTest.php | 298 -------------- app/code/Magento/Elasticsearch/etc/di.xml | 137 ++++++- 69 files changed, 4344 insertions(+), 1191 deletions(-) create mode 100644 app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php create mode 100644 app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php create mode 100644 app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php create mode 100644 app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php create mode 100644 app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php create mode 100644 app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php delete mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php rename app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/{ => FieldProvider}/FieldName/Resolver/CategoryName.php (60%) create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php rename app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/{ => FieldProvider}/FieldName/Resolver/DefaultResolver.php (54%) create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php rename app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/{ => FieldProvider}/FieldName/Resolver/Position.php (62%) create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php create mode 100644 app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php delete mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapperTest.php delete mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php delete mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/ProductFieldMapperTest.php diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 3e6164208b422..7892e18b9ee4c 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -3,11 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\BatchDataMapper; use Magento\Elasticsearch\Model\ResourceModel\Index; use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; -use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Framework\App\ObjectManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; /** * Provide data mapping for categories fields @@ -20,18 +24,30 @@ class CategoryFieldsProvider implements AdditionalFieldsProviderInterface private $resourceIndex; /** - * @var FieldMapperInterface + * @var AttributeProvider */ - private $fieldMapper; + private $attributeAdapterProvider; + + /** + * @var FieldNameResolver + */ + private $fieldNameResolver; /** * @param Index $resourceIndex - * @param FieldMapperInterface $fieldMapper + * @param AttributeProvider|null $attributeAdapterProvider + * @param FieldNameResolver|null $fieldNameResolver */ - public function __construct(Index $resourceIndex, FieldMapperInterface $fieldMapper) - { + public function __construct( + Index $resourceIndex, + AttributeProvider $attributeAdapterProvider = null, + FieldNameResolver $fieldNameResolver = null + ) { $this->resourceIndex = $resourceIndex; - $this->fieldMapper = $fieldMapper; + $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() + ->get(AttributeProvider::class); + $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() + ->get(FieldNameResolver::class); } /** @@ -55,6 +71,7 @@ public function getFields(array $productIds, $storeId) * @param int $productId * @param array $categoryIndexData * @return array + * @throws \Magento\Framework\Exception\LocalizedException */ private function getProductCategoryData($productId, array $categoryIndexData) { @@ -66,9 +83,17 @@ private function getProductCategoryData($productId, array $categoryIndexData) if (count($categoryIds)) { $result = ['category_ids' => $categoryIds]; + $positionAttribute = $this->attributeAdapterProvider->getByAttributeCode('position'); + $categoryNameAttribute = $this->attributeAdapterProvider->getByAttributeCode('category_name'); foreach ($indexData as $data) { - $categoryPositionKey = $this->fieldMapper->getFieldName('position', ['categoryId' => $data['id']]); - $categoryNameKey = $this->fieldMapper->getFieldName('category_name', ['categoryId' => $data['id']]); + $categoryPositionKey = $this->fieldNameResolver->getFieldName( + $positionAttribute, + ['categoryId' => $data['id']] + ); + $categoryNameKey = $this->fieldNameResolver->getFieldName( + $categoryNameAttribute, + ['categoryId' => $data['id']] + ); $result[$categoryPositionKey] = $data['position']; $result[$categoryNameKey] = $data['name']; } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php index bcf0d0bfe26cd..de72485ddb84f 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\DataMapper; use Magento\Catalog\Model\ResourceModel\Eav\Attribute; @@ -14,6 +15,10 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\Model\Adapter\DataMapperInterface; use Magento\Elasticsearch\Model\Adapter\FieldType\Date as DateFieldType; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Framework\App\ObjectManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; /** * @deprecated 100.2.0 @@ -78,6 +83,16 @@ class ProductDataMapper implements DataMapperInterface */ protected $mediaGalleryRoles; + /** + * @var AttributeProvider + */ + private $attributeAdapterProvider; + + /** + * @var FieldNameResolver + */ + private $fieldNameResolver; + /** * Construction for DocumentDataMapper * @@ -87,6 +102,8 @@ class ProductDataMapper implements DataMapperInterface * @param FieldMapperInterface $fieldMapper * @param StoreManagerInterface $storeManager * @param DateFieldType $dateFieldType + * @param AttributeProvider|null $attributeAdapterProvider + * @param FieldNameResolver|null $fieldNameResolver */ public function __construct( Builder $builder, @@ -94,7 +111,9 @@ public function __construct( Index $resourceIndex, FieldMapperInterface $fieldMapper, StoreManagerInterface $storeManager, - DateFieldType $dateFieldType + DateFieldType $dateFieldType, + AttributeProvider $attributeAdapterProvider = null, + FieldNameResolver $fieldNameResolver = null ) { $this->builder = $builder; $this->attributeContainer = $attributeContainer; @@ -102,6 +121,10 @@ public function __construct( $this->fieldMapper = $fieldMapper; $this->storeManager = $storeManager; $this->dateFieldType = $dateFieldType; + $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() + ->get(AttributeProvider::class); + $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() + ->get(FieldNameResolver::class); $this->mediaGalleryRoles = [ self::MEDIA_ROLE_IMAGE, @@ -232,14 +255,14 @@ protected function getProductTierPriceData($data) if (!empty($data)) { $i = 0; foreach ($data as $tierPrice) { - $result['tier_price_id_'.$i] = $tierPrice['price_id']; - $result['tier_website_id_'.$i] = $tierPrice['website_id']; - $result['tier_all_groups_'.$i] = $tierPrice['all_groups']; - $result['tier_cust_group_'.$i] = $tierPrice['cust_group'] == GroupInterface::CUST_GROUP_ALL + $result['tier_price_id_' . $i] = $tierPrice['price_id']; + $result['tier_website_id_' . $i] = $tierPrice['website_id']; + $result['tier_all_groups_' . $i] = $tierPrice['all_groups']; + $result['tier_cust_group_' . $i] = $tierPrice['cust_group'] == GroupInterface::CUST_GROUP_ALL ? '' : $tierPrice['cust_group']; - $result['tier_price_qty_'.$i] = $tierPrice['price_qty']; - $result['tier_website_price_'.$i] = $tierPrice['website_price']; - $result['tier_price_'.$i] = $tierPrice['price']; + $result['tier_price_qty_' . $i] = $tierPrice['price_qty']; + $result['tier_website_price_' . $i] = $tierPrice['website_price']; + $result['tier_price_' . $i] = $tierPrice['price']; $i++; } } @@ -395,13 +418,21 @@ protected function getProductCategoryData($productId, array $categoryIndexData) if (array_key_exists($productId, $categoryIndexData)) { $indexData = $categoryIndexData[$productId]; foreach ($indexData as $categoryData) { - $categoryIds[] = (int) $categoryData['id']; + $categoryIds[] = (int)$categoryData['id']; } if (count($categoryIds)) { $result = ['category_ids' => implode(' ', $categoryIds)]; + $positionAttribute = $this->attributeAdapterProvider->getByAttributeCode('position'); + $categoryNameAttribute = $this->attributeAdapterProvider->getByAttributeCode('category_name'); foreach ($indexData as $data) { - $categoryPositionKey = $this->fieldMapper->getFieldName('position', ['categoryId' => $data['id']]); - $categoryNameKey = $this->fieldMapper->getFieldName('category_name', ['categoryId' => $data['id']]); + $categoryPositionKey = $this->fieldNameResolver->getFieldName( + $positionAttribute, + ['categoryId' => $data['id']] + ); + $categoryNameKey = $this->fieldNameResolver->getFieldName( + $categoryNameAttribute, + ['categoryId' => $data['id']] + ); $result[$categoryPositionKey] = $data['position']; $result[$categoryNameKey] = $data['name']; } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php new file mode 100644 index 0000000000000..b68d5e6f62d14 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; + +/** + * Field type converter from internal index type to elastic service. + */ +class Converter implements ConverterInterface +{ + /** + * Text flags for Elasticsearch index value + */ + private const ES_NO_INDEX = false; + + /** + * Mapping between internal data types and elastic service. + * + * @var array + */ + private $mapping = [ + 'no_index' => self::ES_NO_INDEX, + ]; + + /** + * {@inheritdoc} + */ + public function convert(string $internalType) + { + return $this->mapping[$internalType]; + } +} diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php new file mode 100644 index 0000000000000..21429bc564374 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ResolverInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface + as FieldTypeResolver; + +/** + * Field index resolver that provide index type for attribute in mapping. + * For example we need to set 'no'/false in case when attribute must be present in index data, + * but stay as not indexable. + */ +class IndexResolver implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $converter; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var FieldTypeResolver + */ + private $fieldTypeResolver; + + /** + * @param ConverterInterface $converter + * @param FieldTypeConverterInterface $fieldTypeConverter + * @param FieldTypeResolver $fieldTypeResolver + */ + public function __construct( + ConverterInterface $converter, + FieldTypeConverterInterface $fieldTypeConverter, + FieldTypeResolver $fieldTypeResolver + ) { + $this->converter = $converter; + $this->fieldTypeConverter = $fieldTypeConverter; + $this->fieldTypeResolver = $fieldTypeResolver; + } + + /** + * {@inheritdoc} + */ + public function getFieldIndex(AttributeAdapter $attribute) + { + $index = null; + if (!$attribute->isSearchable() + && !$attribute->isAlwaysIndexable() + && ($this->isStringServiceFieldType($attribute) || $attribute->isComplexType()) + && !(($attribute->isIntegerType() || $attribute->isBooleanType()) + && !$attribute->isUserDefined()) + && !$attribute->isFloatType() + ) { + $index = $this->converter->convert(ConverterInterface::INTERNAL_NO_INDEX_VALUE); + } + + return $index; + } + + /** + * Check if service field type for field set as 'string' + * + * @param AttributeAdapter $attribute + * @return bool + */ + private function isStringServiceFieldType(AttributeAdapter $attribute): bool + { + $serviceFieldType = $this->fieldTypeResolver->getFieldType($attribute); + $stringTypeKey = $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING); + + return $serviceFieldType === $stringTypeKey; + } +} diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php new file mode 100644 index 0000000000000..9cb773adf914d --- /dev/null +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; + +/** + * Field type converter from internal data types to elastic service. + */ +class Converter implements ConverterInterface +{ + /**#@+ + * Text flags for Elasticsearch field types + */ + private const ES_DATA_TYPE_TEXT = 'text'; + private const ES_DATA_TYPE_KEYWORD = 'keyword'; + private const ES_DATA_TYPE_FLOAT = 'float'; + private const ES_DATA_TYPE_INT = 'integer'; + private const ES_DATA_TYPE_DATE = 'date'; + /**#@-*/ + + /** + * Mapping between internal data types and elastic service. + * + * @var array + */ + private $mapping = [ + self::INTERNAL_DATA_TYPE_STRING => self::ES_DATA_TYPE_TEXT, + self::INTERNAL_DATA_TYPE_KEYWORD => self::ES_DATA_TYPE_KEYWORD, + self::INTERNAL_DATA_TYPE_FLOAT => self::ES_DATA_TYPE_FLOAT, + self::INTERNAL_DATA_TYPE_INT => self::ES_DATA_TYPE_INT, + self::INTERNAL_DATA_TYPE_DATE => self::ES_DATA_TYPE_DATE, + ]; + + /** + * {@inheritdoc} + */ + public function convert(string $internalType): string + { + return $this->mapping[$internalType]; + } +} diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php new file mode 100644 index 0000000000000..719af357263d6 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Composite resolver for resolving field type. + */ +class CompositeResolver implements ResolverInterface +{ + /** + * @var ResolverInterface[] + */ + private $items; + + /** + * @param ResolverInterface[] $items + */ + public function __construct(array $items) + { + $this->items = $items; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + $result = null; + foreach ($this->items as $item) { + $result = $item->getFieldType($attribute); + if (null !== $result) { + break; + } + } + + return $result; + } +} diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php new file mode 100644 index 0000000000000..b777eb7e96ba5 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Integer type resolver. + */ +class IntegerType implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var array + */ + private $integerTypeAttributes; + + /** + * @param ConverterInterface $fieldTypeConverter + * @param array $integerTypeAttributes + */ + public function __construct(ConverterInterface $fieldTypeConverter, $integerTypeAttributes = ['category_ids']) + { + $this->fieldTypeConverter = $fieldTypeConverter; + $this->integerTypeAttributes = $integerTypeAttributes; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + if (in_array($attribute->getAttributeCode(), $this->integerTypeAttributes, true) + || (($attribute->isIntegerType() || $attribute->isBooleanType()) + && !$attribute->isUserDefined()) + ) { + return $this->fieldTypeConverter->convert(ConverterInterface::INTERNAL_DATA_TYPE_INT); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php new file mode 100644 index 0000000000000..77ef77aaf8740 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Keyword type resolver. + */ +class KeywordType implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $fieldTypeConverter; + + /** + * @param ConverterInterface $fieldTypeConverter + */ + public function __construct(ConverterInterface $fieldTypeConverter) + { + $this->fieldTypeConverter = $fieldTypeConverter; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + if ($attribute->isComplexType() + || (!$attribute->isSearchable() && !$attribute->isAlwaysIndexable() && $attribute->isFilterable()) + ) { + return $this->fieldTypeConverter->convert(ConverterInterface::INTERNAL_DATA_TYPE_KEYWORD); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php index 87112032e1e27..e34e62a774925 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -3,16 +3,20 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper; -use Magento\Catalog\Api\CategoryListInterface; -use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Eav\Model\Config; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; +use Magento\Framework\App\ObjectManager; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; -use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use \Magento\Customer\Model\Session as CustomerSession; /** * Class ProductFieldMapper @@ -20,60 +24,81 @@ class ProductFieldMapper implements FieldMapperInterface { /** + * @deprecated * @var Config */ protected $eavConfig; /** + * @deprecated * @var FieldType */ protected $fieldType; /** - * Category list. - * - * @var CategoryListInterface + * @deprecated + * @var CustomerSession */ - private $categoryList; + protected $customerSession; /** - * Customer group repository. - * - * @var GroupRepositoryInterface + * @deprecated + * @var StoreManager */ - private $groupRepository; + protected $storeManager; /** - * Search criteria builder. - * - * @var SearchCriteriaBuilder + * @deprecated + * @var Registry + */ + protected $coreRegistry; + + /** + * @var AttributeProvider */ - private $searchCriteriaBuilder; + private $attributeAdapterProvider; /** - * @var ResolverInterface + * @var FieldNameResolver */ private $fieldNameResolver; + /** + * @var FieldProviderInterface + */ + private $fieldProvider; + /** * @param Config $eavConfig * @param FieldType $fieldType - * @param GroupRepositoryInterface $groupRepository - * @param SearchCriteriaBuilder $searchCriteriaBuilder - * @param ResolverInterface $fieldNameResolver + * @param CustomerSession $customerSession + * @param StoreManager $storeManager + * @param Registry $coreRegistry + * @param FieldNameResolver|null $fieldNameResolver + * @param AttributeProvider|null $attributeAdapterProvider + * @param FieldProviderInterface|null $fieldProvider */ public function __construct( Config $eavConfig, FieldType $fieldType, - GroupRepositoryInterface $groupRepository, - SearchCriteriaBuilder $searchCriteriaBuilder, - ResolverInterface $fieldNameResolver + CustomerSession $customerSession, + StoreManager $storeManager, + Registry $coreRegistry, + FieldNameResolver $fieldNameResolver = null, + AttributeProvider $attributeAdapterProvider = null, + FieldProviderInterface $fieldProvider = null ) { $this->eavConfig = $eavConfig; $this->fieldType = $fieldType; - $this->groupRepository = $groupRepository; - $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->fieldNameResolver = $fieldNameResolver; + $this->customerSession = $customerSession; + $this->storeManager = $storeManager; + $this->coreRegistry = $coreRegistry; + $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() + ->get(FieldNameResolver::class); + $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() + ->get(AttributeProvider::class); + $this->fieldProvider = $fieldProvider ?: ObjectManager::getInstance() + ->get(FieldProviderInterface::class); } /** @@ -82,10 +107,12 @@ public function __construct( * @param string $attributeCode * @param array $context * @return string + * @throws \Magento\Framework\Exception\LocalizedException */ public function getFieldName($attributeCode, $context = []) { - return $this->fieldNameResolver->getFieldName($attributeCode, $context); + $attributeAdapter = $this->attributeAdapterProvider->getByAttributeCode($attributeCode); + return $this->fieldNameResolver->getFieldName($attributeAdapter, $context); } /** @@ -96,107 +123,6 @@ public function getFieldName($attributeCode, $context = []) */ public function getAllAttributesTypes($context = []) { - return array_merge( - $this->getAllStaticAttributesTypes(), - $this->getAllDynamicAttributesTypes() - ); - } - - /** - * @param Object $attribute - * @return bool - */ - protected function isAttributeUsedInAdvancedSearch($attribute) - { - return $attribute->getIsVisibleInAdvancedSearch() - || $attribute->getIsFilterable() - || $attribute->getIsFilterableInSearch(); - } - - /** - * Prepare mapping data for static attributes. - * - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @return array - */ - private function getAllStaticAttributesTypes() - { - $attributeCodes = $this->eavConfig->getEntityAttributeCodes(ProductAttributeInterface::ENTITY_TYPE_CODE); - $allAttributes = []; - // List of attributes which are required to be indexable - $alwaysIndexableAttributes = [ - 'category_ids', - 'visibility', - ]; - - foreach ($attributeCodes as $attributeCode) { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - - $allAttributes[$attributeCode] = [ - 'type' => $this->fieldType->getFieldType($attribute), - ]; - - if (!$attribute->getIsSearchable() && !$this->isAttributeUsedInAdvancedSearch($attribute) - && !in_array($attributeCode, $alwaysIndexableAttributes, true) - ) { - if ($attribute->getIsFilterable() || $attribute->getIsFilterableInSearch()) { - $allAttributes[$attributeCode]['type'] = FieldType::ES_DATA_TYPE_KEYWORD; - } else if ($allAttributes[$attributeCode]['type'] === FieldType::ES_DATA_TYPE_TEXT) { - $allAttributes[$attributeCode]['index'] = false; - } - } else if ($attributeCode == "category_ids") { - $allAttributes[$attributeCode] = [ - 'type' => FieldType::ES_DATA_TYPE_INT, - ]; - } - - if ($attribute->usesSource() - || $attribute->getFrontendInput() === 'select' - || $attribute->getFrontendInput() === 'multiselect' - ) { - $allAttributes[$attributeCode]['type'] = FieldType::ES_DATA_TYPE_KEYWORD; - - $allAttributes[$attributeCode . '_value'] = [ - 'type' => FieldType::ES_DATA_TYPE_TEXT, - ]; - } - } - - return $allAttributes; - } - - /** - * Prepare mapping data for dynamic attributes. - * - * @return array - */ - private function getAllDynamicAttributesTypes() - { - $allAttributes = []; - $searchCriteria = $this->searchCriteriaBuilder->create(); - $categories = $this->categoryList->getList($searchCriteria)->getItems(); - foreach ($categories as $category) { - $categoryPositionKey = $this->getFieldName('position', ['categoryId' => $category->getId()]); - $categoryNameKey = $this->getFieldName('category_name', ['categoryId' => $category->getId()]); - $allAttributes[$categoryPositionKey] = [ - 'type' => FieldType::ES_DATA_TYPE_TEXT, - 'index' => false - ]; - $allAttributes[$categoryNameKey] = [ - 'type' => FieldType::ES_DATA_TYPE_TEXT, - 'index' => false - ]; - } - - $groups = $this->groupRepository->getList($searchCriteria)->getItems(); - foreach ($groups as $group) { - $groupPriceKey = $this->getFieldName('price', ['customerGroupId' => $group->getId()]); - $allAttributes[$groupPriceKey] = [ - 'type' => FieldType::ES_DATA_TYPE_FLOAT, - 'store' => true - ]; - } - - return $allAttributes; + return $this->fieldProvider->getFields($context); } } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php index d11603295453d..002a787fd031a 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php @@ -6,15 +6,23 @@ namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter; use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; /** * Class FieldType + * * @api * @since 100.1.0 + * + * @deprecated This class provide not full data about field type. Only basic rules apply on this class. + * @see ResolverInterface */ class FieldType { /**#@+ + * @deprecated + * @see \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + * * Text flags for Elasticsearch field types */ const ES_DATA_TYPE_TEXT = 'text'; @@ -28,12 +36,16 @@ class FieldType /**#@-*/ /** + * @deprecated + * @see ResolverInterface::getFieldType + * * @param AbstractAttribute $attribute * @return string * @since 100.1.0 */ public function getFieldType($attribute) { + trigger_error('Class is deprecated', E_USER_DEPRECATED); $backendType = $attribute->getBackendType(); $frontendInput = $attribute->getFrontendInput(); diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 7d2af3b31d9ac..8feb8eb6088cc 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -3,11 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Elasticsearch\Model\Adapter\BatchDataMapper; use Magento\Elasticsearch\Model\ResourceModel\Index; use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; -use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Framework\App\ObjectManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; /** * Provide data mapping for categories fields @@ -20,18 +24,30 @@ class CategoryFieldsProvider implements AdditionalFieldsProviderInterface private $resourceIndex; /** - * @var FieldMapperInterface + * @var AttributeProvider */ - private $fieldMapper; + private $attributeAdapterProvider; + + /** + * @var FieldNameResolver + */ + private $fieldNameResolver; /** * @param Index $resourceIndex - * @param FieldMapperInterface $fieldMapper + * @param AttributeProvider|null $attributeAdapterProvider + * @param FieldNameResolver|null $fieldNameResolver */ - public function __construct(Index $resourceIndex, FieldMapperInterface $fieldMapper) - { + public function __construct( + Index $resourceIndex, + AttributeProvider $attributeAdapterProvider = null, + FieldNameResolver $fieldNameResolver = null + ) { $this->resourceIndex = $resourceIndex; - $this->fieldMapper = $fieldMapper; + $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() + ->get(AttributeProvider::class); + $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() + ->get(FieldNameResolver::class); } /** @@ -55,6 +71,7 @@ public function getFields(array $productIds, $storeId) * @param int $productId * @param array $categoryIndexData * @return array + * @throws \Magento\Framework\Exception\LocalizedException */ private function getProductCategoryData($productId, array $categoryIndexData) { @@ -66,9 +83,17 @@ private function getProductCategoryData($productId, array $categoryIndexData) if (count($categoryIds)) { $result = ['category_ids' => implode(' ', $categoryIds)]; + $positionAttribute = $this->attributeAdapterProvider->getByAttributeCode('position'); + $categoryNameAttribute = $this->attributeAdapterProvider->getByAttributeCode('category_name'); foreach ($indexData as $data) { - $categoryPositionKey = $this->fieldMapper->getFieldName('position', ['categoryId' => $data['id']]); - $categoryNameKey = $this->fieldMapper->getFieldName('category_name', ['categoryId' => $data['id']]); + $categoryPositionKey = $this->fieldNameResolver->getFieldName( + $positionAttribute, + ['categoryId' => $data['id']] + ); + $categoryNameKey = $this->fieldNameResolver->getFieldName( + $categoryNameAttribute, + ['categoryId' => $data['id']] + ); $result[$categoryPositionKey] = $data['position']; $result[$categoryNameKey] = $data['name']; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php index f97cc89c5c875..1b749fd7039e5 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php @@ -3,13 +3,17 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Elasticsearch\Model\Adapter\BatchDataMapper; -use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\Model\ResourceModel\Index; use Magento\Store\Model\StoreManagerInterface; use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Framework\App\ObjectManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; /** * Provide data mapping for price fields @@ -32,26 +36,36 @@ class PriceFieldsProvider implements AdditionalFieldsProviderInterface private $storeManager; /** - * @var FieldMapperInterface + * @var AttributeProvider + */ + private $attributeAdapterProvider; + + /** + * @var FieldNameResolver */ - private $fieldMapper; + private $fieldNameResolver; /** * @param Index $resourceIndex * @param DataProvider $dataProvider * @param StoreManagerInterface $storeManager - * @param FieldMapperInterface $fieldMapper + * @param AttributeProvider|null $attributeAdapterProvider + * @param FieldNameResolver|null $fieldNameResolver */ public function __construct( Index $resourceIndex, DataProvider $dataProvider, StoreManagerInterface $storeManager, - FieldMapperInterface $fieldMapper + AttributeProvider $attributeAdapterProvider = null, + FieldNameResolver $fieldNameResolver = null ) { $this->resourceIndex = $resourceIndex; $this->dataProvider = $dataProvider; $this->storeManager = $storeManager; - $this->fieldMapper = $fieldMapper; + $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() + ->get(AttributeProvider::class); + $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() + ->get(FieldNameResolver::class); } /** @@ -65,7 +79,7 @@ public function getFields(array $productIds, $storeId) $fields = []; foreach ($productIds as $productId) { - $fields[$productId] = $this->getProductPriceData($productId, $priceData); + $fields[$productId] = $this->getProductPriceData($productId, $storeId, $priceData); } return $fields; @@ -75,18 +89,20 @@ public function getFields(array $productIds, $storeId) * Prepare price index for product * * @param int $productId + * @param int $websiteId * @param array $priceIndexData * @return array */ - private function getProductPriceData($productId, array $priceIndexData) + private function getProductPriceData($productId, $websiteId, array $priceIndexData) { $result = []; if (array_key_exists($productId, $priceIndexData)) { $productPriceIndexData = $priceIndexData[$productId]; + $priceAttribute = $this->attributeAdapterProvider->getByAttributeCode('price'); foreach ($productPriceIndexData as $customerGroupId => $price) { - $fieldName = $this->fieldMapper->getFieldName( - 'price', - ['customerGroupId' => $customerGroupId] + $fieldName = $this->fieldNameResolver->getFieldName( + $priceAttribute, + ['customerGroupId' => $customerGroupId, 'websiteId' => $websiteId] ); $result[$fieldName] = sprintf('%F', $price); } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php index fdf23332fff04..8e69001272b27 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php @@ -23,6 +23,11 @@ class Elasticsearch const BULK_ACTION_UPDATE = 'update'; /**#@-*/ + /** + * Buffer for total fields limit in mapping. + */ + private const MAPPING_TOTAL_FIELDS_BUFFER_LIMIT = 1000; + /**#@-*/ protected $connectionManager; @@ -348,8 +353,13 @@ protected function prepareIndex($storeId, $indexName, $mappedIndexerId) { $this->indexBuilder->setStoreId($storeId); $settings = $this->indexBuilder->build(); - $allAttributeTypes = $this->fieldMapper->getAllAttributesTypes(['entityType' => $mappedIndexerId]); - $settings['index']['mapping']['total_fields']['limit'] = count($allAttributeTypes); + $allAttributeTypes = $this->fieldMapper->getAllAttributesTypes([ + 'entityType' => $mappedIndexerId, + // Use store id instead of website id from context for save existing fields mapping. + // In future websiteId will be eliminated due to index stored per store + 'websiteId' => $storeId + ]); + $settings['index']['mapping']['total_fields']['limit'] = $this->getMappingTotalFieldsLimit($allAttributeTypes); $this->client->createIndex($indexName, ['settings' => $settings]); $this->client->addFieldsMapping( $allAttributeTypes, @@ -359,4 +369,15 @@ protected function prepareIndex($storeId, $indexName, $mappedIndexerId) $this->preparedIndex[$storeId] = $indexName; return $this; } + + /** + * Get total fields limit for mapping. + * + * @param array $allAttributeTypes + * @return int + */ + private function getMappingTotalFieldsLimit(array $allAttributeTypes): int + { + return count($allAttributeTypes) + self::MAPPING_TOTAL_FIELDS_BUFFER_LIMIT; + } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php new file mode 100644 index 0000000000000..0661e86edceb7 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php @@ -0,0 +1,177 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; + +use Magento\Framework\Model\AbstractExtensibleModel; + +/** + * Product attribute adapter for elasticsearch context. + */ +class AttributeAdapter +{ + /** + * @var AbstractExtensibleModel + */ + private $attribute; + + /** + * @var string + */ + private $attributeCode; + + /** + * @param AbstractExtensibleModel $attribute + * @param string $attributeCode + */ + public function __construct( + AbstractExtensibleModel $attribute, + string $attributeCode + ) { + $this->attribute = $attribute; + $this->attributeCode = $attributeCode; + } + + /** + * Check if attribute is filterable. + * + * @return bool + */ + public function isFilterable(): bool + { + return $this->getAttribute()->getIsFilterable() || $this->getAttribute()->getIsFilterableInSearch(); + } + + /** + * Check if attribute is searchable. + * + * @return bool + */ + public function isSearchable(): bool + { + return $this->getAttribute()->getIsSearchable() + || ($this->getAttribute()->getIsVisibleInAdvancedSearch() + || $this->isFilterable()); + } + + /** + * Check if attribute is need to index always. + * + * @return bool + */ + public function isAlwaysIndexable(): bool + { + // List of attributes which are required to be indexable + $alwaysIndexableAttributes = [ + 'category_ids', + 'visibility', + ]; + + return in_array($this->getAttributeCode(), $alwaysIndexableAttributes, true); + } + + /** + * Check if attribute has date/time type. + * + * @return bool + */ + public function isDateTimeType(): bool + { + return in_array($this->getAttribute()->getBackendType(), ['timestamp', 'datetime'], true); + } + + /** + * Check if attribute has float type. + * + * @return bool + */ + public function isFloatType(): bool + { + return $this->getAttribute()->getBackendType() === 'decimal'; + } + + /** + * Check if attribute has integer type. + * + * @return bool + */ + public function isIntegerType(): bool + { + return in_array($this->getAttribute()->getBackendType(), ['int', 'smallint'], true); + } + + /** + * Check if attribute has boolean type. + * + * @return bool + */ + public function isBooleanType(): bool + { + return in_array($this->getAttribute()->getFrontendInput(), ['select', 'boolean'], true) + && $this->getAttribute()->getBackendType() !== 'varchar'; + } + + /** + * Check if attribute has boolean type. + * + * @return bool + */ + public function isComplexType(): bool + { + return in_array($this->getAttribute()->getFrontendInput(), ['select', 'multiselect'], true) + || $this->getAttribute()->usesSource(); + } + + /** + * Check if product attribute is EAV. + * + * @return bool + */ + public function isEavAttribute(): bool + { + return $this->getAttribute() instanceof \Magento\Eav\Api\Data\AttributeInterface; + } + + /** + * Get attribute code. + * + * @return string + */ + public function getAttributeCode(): string + { + return $this->attributeCode; + } + + /** + * Check if attribute is defined by user. + * + * @return string + */ + public function isUserDefined(): string + { + return $this->getAttribute()->getIsUserDefined(); + } + + /** + * Frontend HTML for input element. + * + * @return string + */ + public function getFrontendInput() + { + return $this->getAttribute()->getFrontendInput(); + } + + /** + * Get product attribute instance. + * + * @return AbstractExtensibleModel|\Magento\Eav\Api\Data\AttributeInterface + */ + private function getAttribute(): AbstractExtensibleModel + { + return $this->attribute; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php new file mode 100644 index 0000000000000..de824e4aeedb2 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php @@ -0,0 +1,14 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; + +/** + * Dummy class for Not EAV attribute. + */ +class DummyAttribute extends \Magento\Framework\Model\AbstractExtensibleModel +{ + // +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php new file mode 100644 index 0000000000000..8ae100f177494 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php @@ -0,0 +1,77 @@ +<?php + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; + +use Magento\Eav\Model\Config; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter\DummyAttribute; + +/** + * Provide attribute adapter. + */ +class AttributeProvider +{ + /** + * Object Manager instance + * + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager = null; + + /** + * Instance name to create + * + * @var string + */ + private $instanceName = null; + + /** + * @var Config + */ + private $eavConfig; + + /** + * @var array + */ + private $cachedPool = []; + + /** + * Factory constructor + * + * @param \Magento\Framework\ObjectManagerInterface $objectManager + * @param Config $eavConfig + * @param string $instanceName + */ + public function __construct( + \Magento\Framework\ObjectManagerInterface $objectManager, + Config $eavConfig, + $instanceName = 'Magento\\Elasticsearch\\Model\\Adapter\\FieldMapper\\Product\\AttributeAdapter' + ) { + $this->objectManager = $objectManager; + $this->instanceName = $instanceName; + $this->eavConfig = $eavConfig; + } + + /** + * Create class instance with specified parameters + * + * @param string $attributeCode + * @return AttributeAdapter + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function getByAttributeCode(string $attributeCode): AttributeAdapter + { + if (!isset($this->cachedPool[$attributeCode])) { + $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); + if (null === $attribute) { + $attribute = $this->objectManager->create(DummyAttribute::class); + } + $this->cachedPool[$attributeCode] = $this->objectManager->create( + $this->instanceName, + ['attribute' => $attribute, 'attributeCode' => $attributeCode] + ); + } + + return $this->cachedPool[$attributeCode]; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php new file mode 100644 index 0000000000000..7d0d5fccbcf6c --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php @@ -0,0 +1,39 @@ +<?php + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; + +/** + * Provide fields for product. + */ +class CompositeFieldProvider implements FieldProviderInterface +{ + /** + * @var FieldProviderInterface[] + */ + private $providers; + + /** + * @param array $providers + */ + public function __construct(array $providers) + { + $this->providers = $providers; + } + + /** + * Get fields. + * + * @param array $context + * @return array + */ + public function getFields(array $context = []): array + { + $allAttributes = []; + + foreach ($this->providers as $provider) { + $allAttributes = array_merge($allAttributes, $provider->getFields($context)); + } + + return $allAttributes; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php deleted file mode 100644 index 8c8b58943a5b3..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/NotEavAttribute.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; -use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Eav\Model\Config; - -/** - * Resolver field name for not EAV attribute. - */ -class NotEavAttribute extends Resolver implements ResolverInterface -{ - /** - * @var Config - */ - private $eavConfig; - - /** - * @param ResolverInterface $resolver - * @param Config $eavConfig - */ - public function __construct(ResolverInterface $resolver, Config $eavConfig) - { - parent::__construct($resolver); - $this->eavConfig = $eavConfig; - } - - /** - * {@inheritdoc} - */ - public function getFieldName($attributeCode, $context = []): string - { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - if (!$attribute) { - return $attributeCode; - } - - return $this->getNext()->getFieldName($attributeCode, $context); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php deleted file mode 100644 index ea64972868d0a..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Price.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; - -use Magento\Customer\Model\Session as CustomerSession; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; - -/** - * Resolver field name for price attribute. - */ -class Price extends Resolver implements ResolverInterface -{ - /** - * @var CustomerSession - */ - private $customerSession; - - /** - * @param ResolverInterface $resolver - * @param CustomerSession $customerSession - */ - public function __construct( - ResolverInterface $resolver, - CustomerSession $customerSession - ) { - parent::__construct($resolver); - $this->customerSession = $customerSession; - } - - /** - * {@inheritdoc} - */ - public function getFieldName($attributeCode, $context = []): string - { - if ($attributeCode === 'price') { - $customerGroupId = !empty($context['customerGroupId']) - ? $context['customerGroupId'] - : $this->customerSession->getCustomerGroupId(); - - return 'price_' . $customerGroupId; - } - - return $this->getNext()->getFieldName($attributeCode, $context); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php deleted file mode 100644 index 492fc70848530..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Resolver.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; -use Magento\Framework\Exception\NotFoundException; - -/** - * Abstract class for resolving field name. - */ -abstract class Resolver implements ResolverInterface -{ - /** - * @var ResolverInterface - */ - private $next; - - /** - * @param ResolverInterface $resolver - */ - public function __construct(ResolverInterface $resolver) - { - $this->next = $resolver; - } - - /** - * {@inheritdoc} - */ - public abstract function getFieldName($attributeCode, $context = []): string; - - /** - * {@inheritdoc} - */ - public function getNext(): ResolverInterface - { - if (!$this->hasNext()) { - throw new NotFoundException(__('Next resolver not found.')); - } - - return $this->next; - } - - /** - * {@inheritdoc} - */ - public function hasNext(): bool - { - return null !== $this->next; - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php deleted file mode 100644 index 518cd548536b2..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/SpecialAttribute.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; - -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; - -/** - * Resolver field name for not special attribute. - */ -class SpecialAttribute extends Resolver implements ResolverInterface -{ - /** - * {@inheritdoc} - */ - public function getFieldName($attributeCode, $context = []): string - { - if (in_array($attributeCode, ['id', 'sku', 'store_id', 'visibility'], true)) { - return $attributeCode; - } - - return $this->getNext()->getFieldName($attributeCode, $context); - } -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php deleted file mode 100644 index 0b7bc187ecd68..0000000000000 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/ResolverInterface.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName; - -use Magento\Framework\Exception\NotFoundException; - -/** - * Field name resolver interface. - */ -interface ResolverInterface -{ - /** - * Get field name. - * - * @param $attributeCode - * @param array $context - * @return string - */ - public function getFieldName($attributeCode, $context = []): string; - - /** - * Get next resolver. - * - * @return ResolverInterface - * @throws NotFoundException - */ - public function getNext(): ResolverInterface; - - /** - * Check if next resolver present. - * - * @return bool - */ - public function hasNext(): bool; -} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php new file mode 100644 index 0000000000000..a7773f0afda7e --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php @@ -0,0 +1,134 @@ +<?php + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider; + +use Magento\Catalog\Api\CategoryListInterface; +use Magento\Customer\Api\GroupRepositoryInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface + as IndexTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; +use Magento\Framework\Api\SearchCriteriaBuilder; + +/** + * Provide dynamic fields for product. + */ +class DynamicField implements FieldProviderInterface +{ + /** + * Category list. + * + * @var CategoryListInterface + */ + private $categoryList; + + /** + * Customer group repository. + * + * @var GroupRepositoryInterface + */ + private $groupRepository; + + /** + * Search criteria builder. + * + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var IndexTypeConverterInterface + */ + private $indexTypeConverter; + + /** + * @var AttributeProvider + */ + private $attributeAdapterProvider; + + /** + * @var FieldNameResolver + */ + private $fieldNameResolver; + + /** + * @param FieldTypeConverterInterface $fieldTypeConverter + * @param IndexTypeConverterInterface $indexTypeConverter + * @param GroupRepositoryInterface $groupRepository + * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param CategoryListInterface $categoryList + * @param FieldNameResolver $fieldNameResolver + * @param AttributeProvider $attributeAdapterProvider + */ + public function __construct( + FieldTypeConverterInterface $fieldTypeConverter, + IndexTypeConverterInterface $indexTypeConverter, + GroupRepositoryInterface $groupRepository, + SearchCriteriaBuilder $searchCriteriaBuilder, + CategoryListInterface $categoryList, + FieldNameResolver $fieldNameResolver, + AttributeProvider $attributeAdapterProvider + ) { + $this->groupRepository = $groupRepository; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->fieldTypeConverter = $fieldTypeConverter; + $this->indexTypeConverter = $indexTypeConverter; + $this->categoryList = $categoryList; + $this->fieldNameResolver = $fieldNameResolver; + $this->attributeAdapterProvider = $attributeAdapterProvider; + } + + /** + * {@inheritdoc} + */ + public function getFields(array $context = []): array + { + $allAttributes = []; + $searchCriteria = $this->searchCriteriaBuilder->create(); + $categories = $this->categoryList->getList($searchCriteria)->getItems(); + $positionAttribute = $this->attributeAdapterProvider->getByAttributeCode('position'); + $categoryNameAttribute = $this->attributeAdapterProvider->getByAttributeCode('category_name'); + foreach ($categories as $category) { + $categoryPositionKey = $this->fieldNameResolver->getFieldName( + $positionAttribute, + ['categoryId' => $category->getId()] + ); + $categoryNameKey = $this->fieldNameResolver->getFieldName( + $categoryNameAttribute, + ['categoryId' => $category->getId()] + ); + $allAttributes[$categoryPositionKey] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING), + 'index' => $this->indexTypeConverter->convert(IndexTypeConverterInterface::INTERNAL_NO_INDEX_VALUE) + ]; + $allAttributes[$categoryNameKey] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING), + 'index' => $this->indexTypeConverter->convert(IndexTypeConverterInterface::INTERNAL_NO_INDEX_VALUE) + ]; + } + + $groups = $this->groupRepository->getList($searchCriteria)->getItems(); + $priceAttribute = $this->attributeAdapterProvider->getByAttributeCode('price'); + foreach ($groups as $group) { + $groupPriceKey = $this->fieldNameResolver->getFieldName( + $priceAttribute, + ['customerGroupId' => $group->getId(), 'websiteId' => $context['websiteId']] + ); + $allAttributes[$groupPriceKey] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_FLOAT), + 'store' => true + ]; + } + + return $allAttributes; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php new file mode 100644 index 0000000000000..bd24fe6fa82a3 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +/** + * Field type converter from internal index type to elastic service. + */ +class Converter implements ConverterInterface +{ + /** + * Text flags for Elasticsearch index value + */ + private const ES_NO_INDEX = 'no'; + + /** + * Mapping between internal data types and elastic service. + * + * @var array + */ + private $mapping = [ + 'no_index' => self::ES_NO_INDEX, + ]; + + /** + * {@inheritdoc} + */ + public function convert(string $internalType) + { + return $this->mapping[$internalType]; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php new file mode 100644 index 0000000000000..8199639fb8045 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +/** + * Field type converter from internal index value to elastic service. + */ +interface ConverterInterface +{ + /**#@+ + * Text flags for internal no index value. + */ + public const INTERNAL_NO_INDEX_VALUE = 'no_index'; + public const INTERNAL_INDEX_VALUE = 'index'; + + /** + * Get service field type. + * + * @param string $internalType + * @return string|boolean + */ + public function convert(string $internalType); +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php new file mode 100644 index 0000000000000..5a7203bf30bf6 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; + +/** + * Field index resolver that provide index type for attribute in mapping. + * For example we need to set 'no'/false in case when attribute must be present in index data, + * but stay as not indexable. + */ +class IndexResolver implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $converter; + + /** + * @param ConverterInterface $converter + */ + public function __construct(ConverterInterface $converter) + { + $this->converter = $converter; + } + + /** + * {@inheritdoc} + */ + public function getFieldIndex(AttributeAdapter $attribute) + { + $index = null; + if (!$attribute->isSearchable() && !$attribute->isAlwaysIndexable()) { + $index = $this->converter->convert(ConverterInterface::INTERNAL_NO_INDEX_VALUE); + } + + return $index; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php new file mode 100644 index 0000000000000..fb87e0756d621 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; + +/** + * Field index type resolver interface. + */ +interface ResolverInterface +{ + /** + * Get field index. + * + * @param AttributeAdapter $attribute + * @return string|boolean + */ + public function getFieldIndex(AttributeAdapter $attribute); +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php similarity index 60% rename from app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php rename to app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php index 9e012c1427218..1ad42a55cbbd4 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php @@ -4,16 +4,18 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; +use Magento\Framework\App\ObjectManager; /** * Resolver field name for Category name attribute. */ -class CategoryName extends Resolver implements ResolverInterface +class CategoryName implements ResolverInterface { /** * @var StoreManager @@ -26,30 +28,29 @@ class CategoryName extends Resolver implements ResolverInterface private $coreRegistry; /** - * @param ResolverInterface $resolver * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( - ResolverInterface $resolver, - StoreManager $storeManager, - Registry $coreRegistry + StoreManager $storeManager = null, + Registry $coreRegistry = null ) { - parent::__construct($resolver); - $this->storeManager = $storeManager; - $this->coreRegistry = $coreRegistry; + $this->storeManager = $storeManager ?: ObjectManager::getInstance() + ->get(StoreManager::class); + $this->coreRegistry = $coreRegistry ?: ObjectManager::getInstance() + ->get(Registry::class); } /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []): string + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { - if ($attributeCode === 'category_name') { + if ($attribute->getAttributeCode() === 'category_name') { return 'name_category_' . $this->resolveCategoryId($context); } - return $this->getNext()->getFieldName($attributeCode, $context); + return null; } /** @@ -57,8 +58,9 @@ public function getFieldName($attributeCode, $context = []): string * * @param array $context * @return int + * @throws \Magento\Framework\Exception\NoSuchEntityException */ - private function resolveCategoryId($context) + private function resolveCategoryId($context): int { if (isset($context['categoryId'])) { $id = $context['categoryId']; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php new file mode 100644 index 0000000000000..81ce3bf030806 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; + +/** + * Composite class for resolving field name. + */ +class CompositeResolver implements ResolverInterface +{ + /** + * @var ResolverInterface[] + */ + private $items; + + /** + * @param array $items + */ + public function __construct(array $items) + { + $this->items = $items; + } + + /** + * {@inheritdoc} + */ + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string + { + $result = null; + foreach ($this->items as $item) { + $result = $item->getFieldName($attribute, $context); + if (null !== $result) { + break; + } + } + + return $result; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php similarity index 54% rename from app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php rename to app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php index afc0b6a0c6f99..ab5486f3af292 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php @@ -4,58 +4,57 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; -use Magento\Eav\Model\Config; -use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; -use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface + as FieldTypeResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; /** * Default name resolver. */ -class DefaultResolver extends Resolver implements ResolverInterface +class DefaultResolver implements ResolverInterface { /** - * @var Config + * @var FieldTypeResolver */ - private $eavConfig; + private $fieldTypeResolver; /** - * @var FieldType + * @var FieldTypeConverterInterface */ - private $fieldType; + private $fieldTypeConverter; /** - * @param ResolverInterface $resolver - * @param Config $eavConfig - * @param FieldType $fieldType + * @param FieldTypeResolver $fieldTypeResolver + * @param FieldTypeConverterInterface $fieldTypeConverter */ public function __construct( - ResolverInterface $resolver, - Config $eavConfig, - FieldType $fieldType + FieldTypeResolver $fieldTypeResolver, + FieldTypeConverterInterface $fieldTypeConverter ) { - parent::__construct($resolver); - $this->eavConfig = $eavConfig; - $this->fieldType = $fieldType; + $this->fieldTypeResolver = $fieldTypeResolver; + $this->fieldTypeConverter = $fieldTypeConverter; } /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []): string + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - $fieldType = $this->fieldType->getFieldType($attribute); + $fieldType = $this->fieldTypeResolver->getFieldType($attribute); + $attributeCode = $attribute->getAttributeCode(); $frontendInput = $attribute->getFrontendInput(); if (empty($context['type'])) { $fieldName = $attributeCode; } elseif ($context['type'] === FieldMapperInterface::TYPE_FILTER) { - if (in_array($fieldType, ['string', FieldType::ES_DATA_TYPE_TEXT], true)) { + if ($this->isStringServiceFieldType($fieldType)) { return $this->getFieldName( - $attributeCode, + $attribute, array_merge($context, ['type' => FieldMapperInterface::TYPE_QUERY]) ); } @@ -69,6 +68,19 @@ public function getFieldName($attributeCode, $context = []): string return $fieldName; } + /** + * Check if service field type for field set as 'string' + * + * @param string $serviceFieldType + * @return bool + */ + private function isStringServiceFieldType(string $serviceFieldType): bool + { + $stringTypeKey = $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING); + + return $serviceFieldType === $stringTypeKey; + } + /** * @param string $frontendInput * @param string $fieldType @@ -95,7 +107,7 @@ private function getRefinedFieldName($frontendInput, $fieldType, $attributeCode) { switch ($frontendInput) { case 'select': - return in_array($fieldType, ['text','integer'], true) ? $attributeCode . '_value' : $attributeCode; + return in_array($fieldType, ['text', 'integer'], true) ? $attributeCode . '_value' : $attributeCode; case 'boolean': return $fieldType === 'integer' ? $attributeCode . '_value' : $attributeCode; default: diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php new file mode 100644 index 0000000000000..094148aa3e632 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; + +/** + * Resolver field name for not EAV attribute. + */ +class NotEavAttribute implements ResolverInterface +{ + /** + * {@inheritdoc} + */ + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string + { + if (!$attribute->isEavAttribute()) { + return $attribute->getAttributeCode(); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php similarity index 62% rename from app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php rename to app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php index d4839012f0b8c..beb1a675e89da 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldName/Resolver/Position.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php @@ -4,16 +4,18 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver; +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; +use Magento\Framework\App\ObjectManager; /** * Resolver field name for position attribute. */ -class Position extends Resolver implements ResolverInterface +class Position implements ResolverInterface { /** * @var StoreManager @@ -26,30 +28,29 @@ class Position extends Resolver implements ResolverInterface private $coreRegistry; /** - * @param ResolverInterface $resolver * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( - ResolverInterface $resolver, - StoreManager $storeManager, - Registry $coreRegistry + StoreManager $storeManager = null, + Registry $coreRegistry = null ) { - parent::__construct($resolver); - $this->storeManager = $storeManager; - $this->coreRegistry = $coreRegistry; + $this->storeManager = $storeManager ?: ObjectManager::getInstance() + ->get(StoreManager::class); + $this->coreRegistry = $coreRegistry ?: ObjectManager::getInstance() + ->get(Registry::class); } /** * {@inheritdoc} */ - public function getFieldName($attributeCode, $context = []): string + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { - if ($attributeCode === 'position') { + if ($attribute->getAttributeCode() === 'position') { return 'position_category_' . $this->resolveCategoryId($context); } - return $this->getNext()->getFieldName($attributeCode, $context); + return null; } /** @@ -57,6 +58,7 @@ public function getFieldName($attributeCode, $context = []): string * * @param array $context * @return int + * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function resolveCategoryId($context) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php new file mode 100644 index 0000000000000..4449ec57523b9 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; + +/** + * Resolver field name for price attribute. + */ +class Price implements ResolverInterface +{ + /** + * @var CustomerSession + */ + private $customerSession; + + /** + * @var StoreManager + */ + private $storeManager; + + /** + * @param CustomerSession $customerSession + * @param StoreManager $storeManager + */ + public function __construct(CustomerSession $customerSession, StoreManager $storeManager) + { + $this->customerSession = $customerSession; + $this->storeManager = $storeManager; + } + + /** + * {@inheritdoc} + */ + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string + { + if ($attribute->getAttributeCode() === 'price') { + $customerGroupId = !empty($context['customerGroupId']) + ? $context['customerGroupId'] + : $this->customerSession->getCustomerGroupId(); + $websiteId = !empty($context['websiteId']) + ? $context['websiteId'] + : $this->storeManager->getStore()->getWebsiteId(); + + return 'price_' . $customerGroupId . '_' . $websiteId; + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php new file mode 100644 index 0000000000000..14906fa5cee82 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; + +/** + * Resolver field name for not special attribute. + */ +class SpecialAttribute implements ResolverInterface +{ + /** + * {@inheritdoc} + */ + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string + { + if (in_array($attribute->getAttributeCode(), ['id', 'sku', 'store_id', 'visibility'], true)) { + return $attribute->getAttributeCode(); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php new file mode 100644 index 0000000000000..ecc46d2607cf8 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; + +/** + * Field name resolver for preparing field key for elasticsearch mapping by attribute. + */ +interface ResolverInterface +{ + /** + * Get field name. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string + */ + public function getFieldName(AttributeAdapter $attribute, $context = []): ?string; +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php new file mode 100644 index 0000000000000..be8ef76e666fe --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; + +/** + * Field type converter from internal data types to elastic service. + */ +class Converter implements ConverterInterface +{ + /**#@+ + * Text flags for Elasticsearch field types + */ + private const ES_DATA_TYPE_STRING = 'string'; + private const ES_DATA_TYPE_FLOAT = 'float'; + private const ES_DATA_TYPE_INT = 'integer'; + private const ES_DATA_TYPE_DATE = 'date'; + /**#@-*/ + + /** + * Mapping between internal data types and elastic service. + * + * @var array + */ + private $mapping = [ + self::INTERNAL_DATA_TYPE_STRING => self::ES_DATA_TYPE_STRING, + self::INTERNAL_DATA_TYPE_KEYWORD => self::ES_DATA_TYPE_STRING, + self::INTERNAL_DATA_TYPE_FLOAT => self::ES_DATA_TYPE_FLOAT, + self::INTERNAL_DATA_TYPE_INT => self::ES_DATA_TYPE_INT, + self::INTERNAL_DATA_TYPE_DATE => self::ES_DATA_TYPE_DATE, + ]; + + /** + * {@inheritdoc} + */ + public function convert(string $internalType): string + { + return $this->mapping[$internalType]; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php new file mode 100644 index 0000000000000..e5ec1ce445ab2 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; + +/** + * @api + * Field type converter from internal data types to elastic service. + */ +interface ConverterInterface +{ + /**#@+ + * Text flags for internal field types + */ + public const INTERNAL_DATA_TYPE_STRING = 'string'; + public const INTERNAL_DATA_TYPE_FLOAT = 'float'; + public const INTERNAL_DATA_TYPE_INT = 'integer'; + public const INTERNAL_DATA_TYPE_DATE = 'date'; + public const INTERNAL_DATA_TYPE_KEYWORD = 'keyword'; + /**#@-*/ + + /** + * Get service field type. + * + * @param string $internalType + * @return string + */ + public function convert(string $internalType): string; +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php new file mode 100644 index 0000000000000..7a4c06c56d095 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Composite resolver for resolving field type. + */ +class CompositeResolver implements ResolverInterface +{ + /** + * @var ResolverInterface[] + */ + private $items; + + /** + * @param ResolverInterface[] $items + */ + public function __construct(array $items) + { + $this->items = $items; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + $result = null; + foreach ($this->items as $item) { + $result = $item->getFieldType($attribute); + if (null !== $result) { + break; + } + } + + return $result; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php new file mode 100644 index 0000000000000..ff029ff8610f5 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Date/Time type resolver. + */ +class DateTimeType implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $fieldTypeConverter; + + /** + * @param ConverterInterface $fieldTypeConverter + */ + public function __construct(ConverterInterface $fieldTypeConverter) + { + $this->fieldTypeConverter = $fieldTypeConverter; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + if ($attribute->isDateTimeType()) { + return $this->fieldTypeConverter->convert(ConverterInterface::INTERNAL_DATA_TYPE_DATE); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php new file mode 100644 index 0000000000000..8e754cddd3e92 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Default field type resolver. + */ +class DefaultResolver implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $fieldTypeConverter; + + /** + * @param ConverterInterface $fieldTypeConverter + */ + public function __construct(ConverterInterface $fieldTypeConverter) + { + $this->fieldTypeConverter = $fieldTypeConverter; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + return $this->fieldTypeConverter->convert(ConverterInterface::INTERNAL_DATA_TYPE_STRING); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php new file mode 100644 index 0000000000000..9fe03d4cbab49 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Float type resolver. + */ +class FloatType implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $fieldTypeConverter; + + /** + * @param ConverterInterface $fieldTypeConverter + */ + public function __construct(ConverterInterface $fieldTypeConverter) + { + $this->fieldTypeConverter = $fieldTypeConverter; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + if ($attribute->isFloatType()) { + return $this->fieldTypeConverter->convert(ConverterInterface::INTERNAL_DATA_TYPE_FLOAT); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php new file mode 100644 index 0000000000000..c4280505f1190 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; + +/** + * Integer type resolver. + */ +class IntegerType implements ResolverInterface +{ + /** + * @var ConverterInterface + */ + private $fieldTypeConverter; + + /** + * @param ConverterInterface $fieldTypeConverter + */ + public function __construct(ConverterInterface $fieldTypeConverter) + { + $this->fieldTypeConverter = $fieldTypeConverter; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(AttributeAdapter $attribute): ?string + { + if (($attribute->isIntegerType() || $attribute->isBooleanType()) + && !$attribute->isUserDefined() + ) { + return $this->fieldTypeConverter->convert(ConverterInterface::INTERNAL_DATA_TYPE_INT); + } + + return null; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php new file mode 100644 index 0000000000000..118a440cddef2 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; + +/** + * Field type resolver interface. + */ +interface ResolverInterface +{ + /** + * Get field type. + * + * @param AttributeAdapter $attribute + * @return string + */ + public function getFieldType(AttributeAdapter $attribute): ?string; +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php new file mode 100644 index 0000000000000..89748d6428e4d --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php @@ -0,0 +1,112 @@ +<?php + +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider; + +use Magento\Eav\Model\Config; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface + as IndexTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface + as FieldTypeResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ResolverInterface + as FieldIndexResolver; + +/** + * Provide static fields for product. + */ +class StaticField implements FieldProviderInterface +{ + /** + * @var Config + */ + private $eavConfig; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var IndexTypeConverterInterface + */ + private $indexTypeConverter; + + /** + * @var AttributeProvider + */ + private $attributeAdapterProvider; + + /** + * @var FieldTypeResolver + */ + private $fieldTypeResolver; + + /** + * @var FieldIndexResolver + */ + private $fieldIndexResolver; + + /** + * @param Config $eavConfig + * @param FieldTypeConverterInterface $fieldTypeConverter + * @param IndexTypeConverterInterface $indexTypeConverter + * @param FieldTypeResolver $fieldTypeResolver + * @param FieldIndexResolver $fieldIndexResolver + * @param AttributeProvider $attributeAdapterProvider + */ + public function __construct( + Config $eavConfig, + FieldTypeConverterInterface $fieldTypeConverter, + IndexTypeConverterInterface $indexTypeConverter, + FieldTypeResolver $fieldTypeResolver, + FieldIndexResolver $fieldIndexResolver, + AttributeProvider $attributeAdapterProvider + ) { + $this->eavConfig = $eavConfig; + $this->fieldTypeConverter = $fieldTypeConverter; + $this->indexTypeConverter = $indexTypeConverter; + $this->fieldTypeResolver = $fieldTypeResolver; + $this->fieldIndexResolver = $fieldIndexResolver; + $this->attributeAdapterProvider = $attributeAdapterProvider; + } + + /** + * {@inheritdoc} + */ + public function getFields(array $context = []): array + { + $attributes = $this->eavConfig->getEntityAttributes(ProductAttributeInterface::ENTITY_TYPE_CODE); + $allAttributes = []; + + foreach ($attributes as $attribute) { + $attributeAdapter = $this->attributeAdapterProvider->getByAttributeCode($attribute->getAttributeCode()); + $code = $attributeAdapter->getAttributeCode(); + + $allAttributes[$code] = [ + 'type' => $this->fieldTypeResolver->getFieldType($attributeAdapter), + ]; + + $index = $this->fieldIndexResolver->getFieldIndex($attributeAdapter); + if (null !== $index) { + $allAttributes[$code]['index'] = $index; + } + + if ($attributeAdapter->isComplexType()) { + $allAttributes[$code . '_value'] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING) + ]; + } + } + + $allAttributes['store_id'] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING), + 'index' => $this->indexTypeConverter->convert(IndexTypeConverterInterface::INTERNAL_NO_INDEX_VALUE), + ]; + + return $allAttributes; + } +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php new file mode 100644 index 0000000000000..2a68e3e2a3708 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; + +/** + * Product fields provider. + * Provide fields mapping configuration for elasticsearch service of internal product attributes. + */ +interface FieldProviderInterface +{ + /** + * Get fields. + * + * @param array $context + * @return array + */ + public function getFields(array $context = []): array; +} diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php index e78983c62f6d2..657605bbd019b 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -5,53 +5,13 @@ */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper; -use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\ProductFieldMapper as Elasticsearch5ProductFieldMapper; -use Magento\Elasticsearch\Model\Adapter\FieldType; /** * Class ProductFieldMapper */ class ProductFieldMapper extends Elasticsearch5ProductFieldMapper implements FieldMapperInterface { - /** - * @return array - */ - private function getAllStaticAttributesTypes() - { - $allAttributes = []; - $attributeCodes = $this->eavConfig->getEntityAttributeCodes(ProductAttributeInterface::ENTITY_TYPE_CODE); - // List of attributes which are required to be indexable - $alwaysIndexableAttributes = [ - 'category_ids', - 'visibility', - ]; - - foreach ($attributeCodes as $attributeCode) { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); - - $allAttributes[$attributeCode] = [ - 'type' => $this->fieldType->getFieldType($attribute) - ]; - - if (!$attribute->getIsSearchable() && !$this->isAttributeUsedInAdvancedSearch($attribute) - && !in_array($attributeCode, $alwaysIndexableAttributes, true) - ) { - $allAttributes[$attributeCode] = array_merge( - $allAttributes[$attributeCode], - ['index' => 'no'] - ); - } - - if ($attribute->getFrontendInput() === 'select' || $attribute->getFrontendInput() === 'multiselect') { - $allAttributes[$attributeCode . '_value'] = [ - 'type' => FieldType::ES_DATA_TYPE_STRING, - ]; - } - } - - return $allAttributes; - } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php index 4315597a3cf58..be6462156c471 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php @@ -6,15 +6,23 @@ namespace Magento\Elasticsearch\Model\Adapter; use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface; /** * Class FieldType + * * @api * @since 100.1.0 + * + * @deprecated This class provide not full data about field type. Only basic rules apply on this class. + * @see ResolverInterface */ class FieldType { /**#@+ + * @deprecated + * @see \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + * * Text flags for Elasticsearch field types */ const ES_DATA_TYPE_STRING = 'string'; @@ -27,12 +35,15 @@ class FieldType /**#@-*/ /** + * @deprecated + * @see ResolverInterface::getFieldType + * * @param AbstractAttribute $attribute * @return string - * @since 100.1.0 */ public function getFieldType($attribute) { + trigger_error('Class is deprecated', E_USER_DEPRECATED); $backendType = $attribute->getBackendType(); $frontendInput = $attribute->getFrontendInput(); diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php new file mode 100644 index 0000000000000..a4503924c8455 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php @@ -0,0 +1,161 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface + as FieldTypeResolver; + +class IndexResolverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver + */ + private $resolver; + + /** + * @var ConverterInterface + */ + private $converter; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var FieldTypeResolver + */ + private $fieldTypeResolver; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->converter = $this->getMockBuilder(ConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + $this->fieldTypeResolver = $this->getMockBuilder(FieldTypeResolver::class) + ->disableOriginalConstructor() + ->setMethods(['getFieldType']) + ->getMockForAbstractClass(); + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver::class, + [ + 'converter' => $this->converter, + 'fieldTypeConverter' => $this->fieldTypeConverter, + 'fieldTypeResolver' => $this->fieldTypeResolver, + ] + ); + } + + /** + * @dataProvider getFieldIndexProvider + * @param $isSearchable + * @param $isAlwaysIndexable + * @param $stringServiceFieldType + * @param $isComplexType + * @param $isIntegerType + * @param $isBooleanType + * @param $isUserDefined + * @param $isFloatType + * @param $serviceFieldType + * @param $expected + * @return void + */ + public function testGetFieldName( + $isSearchable, + $isAlwaysIndexable, + $isComplexType, + $isIntegerType, + $isBooleanType, + $isUserDefined, + $isFloatType, + $serviceFieldType, + $expected + ) { + $this->converter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + $this->fieldTypeResolver->expects($this->any()) + ->method('getFieldType') + ->willReturn($serviceFieldType); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('string'); + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods([ + 'isSearchable', + 'isAlwaysIndexable', + 'isComplexType', + 'isIntegerType', + 'isBooleanType', + 'isUserDefined', + 'isFloatType', + ]) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isSearchable') + ->willReturn($isSearchable); + $attributeMock->expects($this->any()) + ->method('isAlwaysIndexable') + ->willReturn($isAlwaysIndexable); + $attributeMock->expects($this->any()) + ->method('isComplexType') + ->willReturn($isComplexType); + $attributeMock->expects($this->any()) + ->method('isIntegerType') + ->willReturn($isIntegerType); + $attributeMock->expects($this->any()) + ->method('isBooleanType') + ->willReturn($isBooleanType); + $attributeMock->expects($this->any()) + ->method('isUserDefined') + ->willReturn($isUserDefined); + $attributeMock->expects($this->any()) + ->method('isFloatType') + ->willReturn($isFloatType); + + $this->assertEquals( + $expected, + $this->resolver->getFieldIndex($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldIndexProvider() + { + return [ + [true, true, true, true, true, true, true, 'string', null], + [false, false, true, false, false, false, false, 'string', 'something'], + [false, false, true, false, false, false, false, 'string', 'something'], + [false, false, false, false, false, false, false, 'string', 'something'], + [false, false, false, false, false, false, false, 'int', null], + [false, false, true, true, false, true, false, 'string', 'something'], + [false, false, true, false, true, true, false, 'string', 'something'], + [false, false, true, false, true, false, false, 'string', null], + [false, false, true, false, true, true, true, 'string', null], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php new file mode 100644 index 0000000000000..d4536e4a53b62 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class IntegerTypeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType + */ + private $resolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType::class, + [ + 'fieldTypeConverter' => $this->fieldTypeConverter, + ] + ); + } + + /** + * @dataProvider getFieldTypeProvider + * @param $attributeCode + * @param $isIntegerType + * @param $isBooleanType + * @param $isUserDefined + * @param $expected + * @return void + */ + public function testGetFieldType($attributeCode, $isIntegerType, $isBooleanType, $isUserDefined, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode', 'isIntegerType', 'isBooleanType', 'isUserDefined']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $attributeMock->expects($this->any()) + ->method('isIntegerType') + ->willReturn($isIntegerType); + $attributeMock->expects($this->any()) + ->method('isBooleanType') + ->willReturn($isBooleanType); + $attributeMock->expects($this->any()) + ->method('isUserDefined') + ->willReturn($isUserDefined); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + + $this->assertEquals( + $expected, + $this->resolver->getFieldType($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + ['category_ids', true, true, true, 'something'], + ['category_ids', false, false, false, 'something'], + ['type', true, false, false, 'something'], + ['type', false, true, false, 'something'], + ['type', true, true, true, ''], + ['type', false, false, true, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php new file mode 100644 index 0000000000000..cd0b88e6ce51d --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class KeywordTypeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType + */ + private $resolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType::class, + [ + 'fieldTypeConverter' => $this->fieldTypeConverter, + ] + ); + } + + /** + * @dataProvider getFieldTypeProvider + * @param $isComplexType + * @param $isSearchable + * @param $isAlwaysIndexable + * @param $isFilterable + * @param $expected + * @return void + */ + public function testGetFieldType($isComplexType, $isSearchable, $isAlwaysIndexable, $isFilterable, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['isComplexType', 'isSearchable', 'isAlwaysIndexable', 'isFilterable']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isComplexType') + ->willReturn($isComplexType); + $attributeMock->expects($this->any()) + ->method('isSearchable') + ->willReturn($isSearchable); + $attributeMock->expects($this->any()) + ->method('isAlwaysIndexable') + ->willReturn($isAlwaysIndexable); + $attributeMock->expects($this->any()) + ->method('isFilterable') + ->willReturn($isFilterable); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + + $this->assertEquals( + $expected, + $this->resolver->getFieldType($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + [true, true, true, true, 'something'], + [true, false, false, false, 'something'], + [true, false, false, true, 'something'], + [false, false, false, true, 'something'], + [false, false, false, false, ''], + [false, false, true, false, ''], + [false, true, false, false, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapperTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapperTest.php deleted file mode 100644 index 6ee32a58698c6..0000000000000 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapperTest.php +++ /dev/null @@ -1,296 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper; - -use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; - -class ProductFieldMapperTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\ProductFieldMapper - */ - protected $mapper; - - /** - * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject - */ - protected $eavConfig; - - /** - * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject - */ - protected $coreRegistry; - - /** - * @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject - */ - protected $customerSession; - - /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $storeManager; - - /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute|\PHPUnit_Framework_MockObject_MockObject - */ - protected $eavAttributeResource; - - /** - * @var FieldType|\PHPUnit_Framework_MockObject_MockObject - */ - protected $fieldType; - - /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $store; - - /** - * Set up test environment - * - * @return void - */ - protected function setUp() - { - $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class) - ->disableOriginalConstructor() - ->setMethods(['getEntityType', 'getAttribute', 'getEntityAttributeCodes']) - ->getMock(); - - $this->fieldType = $this->getMockBuilder(FieldType::class) - ->disableOriginalConstructor() - ->setMethods(['getFieldType']) - ->getMock(); - - $this->customerSession = $this->getMockBuilder(\Magento\Customer\Model\Session::class) - ->disableOriginalConstructor() - ->setMethods(['getCustomerGroupId']) - ->getMock(); - - $this->storeManager = $this->storeManager = $this->getMockForAbstractClass( - \Magento\Store\Model\StoreManagerInterface::class, - [], - '', - false - ); - - $this->store = $this->getMockForAbstractClass( - \Magento\Store\Api\Data\StoreInterface::class, - [], - '', - false, - false, - true, - ['getWebsiteId', 'getRootCategoryId'] - ); - - $this->coreRegistry = $this->createMock(\Magento\Framework\Registry::class); - - $objectManager = new ObjectManagerHelper($this); - - $this->eavAttributeResource = $this->createPartialMock( - \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class, - [ - '__wakeup', - 'getBackendType', - 'getFrontendInput' - ] - ); - - $this->mapper = $objectManager->getObject( - \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\ProductFieldMapper::class, - [ - 'eavConfig' => $this->eavConfig, - 'storeManager' => $this->storeManager, - 'fieldType' => $this->fieldType, - 'customerSession' => $this->customerSession, - 'coreRegistry' => $this->coreRegistry - ] - ); - } - - /** - * @dataProvider attributeCodeProvider - * @param string $attributeCode - * @param string $fieldName - * @param string $fieldType - * @param array $context - * - * @return void - */ - public function testGetFieldName($attributeCode, $fieldName, $fieldType, $context = []) - { - $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) - ->setMethods(['getBackendType', 'getFrontendInput', 'getAttribute']) - ->disableOriginalConstructor() - ->getMock(); - - $this->customerSession->expects($this->any()) - ->method('getCustomerGroupId') - ->willReturn('0'); - - $this->storeManager->expects($this->any()) - ->method('getStore') - ->willReturn($this->store); - $this->store->expects($this->any()) - ->method('getWebsiteId') - ->willReturn('1'); - $this->store->expects($this->any()) - ->method('getRootCategoryId') - ->willReturn('1'); - - $this->eavConfig->expects($this->any())->method('getAttribute') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode) - ->willReturn($attributeMock); - - $attributeMock->expects($this->any())->method('getFrontendInput') - ->will($this->returnValue('select')); - - $this->fieldType->expects($this->any())->method('getFieldType') - ->with($attributeMock) - ->willReturn($fieldType); - - $this->assertEquals( - $fieldName, - $this->mapper->getFieldName($attributeCode, $context) - ); - } - - /** - * @return void - */ - public function testGetFieldNameWithoutAttribute() - { - $this->eavConfig->expects($this->any())->method('getAttribute') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, 'attr1') - ->willReturn(''); - - $this->assertEquals( - 'attr1', - $this->mapper->getFieldName('attr1', []) - ); - } - - /** - * @dataProvider attributeProvider - * @param string $attributeCode - * @param string $inputType - * @param array $searchAttributes - * @param array $expected - * @return void - */ - public function testGetAllAttributesTypes($attributeCode, $inputType, $searchAttributes, $expected) - { - $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->eavConfig->expects($this->any())->method('getEntityAttributeCodes') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE) - ->willReturn([$attributeCode]); - - $this->eavConfig->expects($this->any())->method('getAttribute') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode) - ->willReturn($attributeMock); - - $this->fieldType->expects($this->once())->method('getFieldType')->willReturn(FieldType::ES_DATA_TYPE_INT); - - $attributeMock->expects($this->any()) - ->method('getIsSearchable') - ->willReturn($searchAttributes['searchable']); - $attributeMock->expects($this->any()) - ->method('getIsFilterable') - ->willReturn($searchAttributes['filterable']); - $attributeMock->expects($this->any()) - ->method('getIsFilterableInSearch') - ->willReturn($searchAttributes['filterableInSearch']); - $attributeMock->expects($this->any()) - ->method('getIsVisibleInAdvancedSearch') - ->willReturn($searchAttributes['advSearch']); - - $attributeMock->expects($this->any())->method('getFrontendInput') - ->will($this->returnValue($inputType)); - - $this->assertEquals( - $expected, - $this->mapper->getAllAttributesTypes() - ); - } - - /** - * @return array - */ - public function attributeCodeProvider() - { - return [ - ['id', 'id', 'text'], - ['status', 'status', 'text'], - ['status', 'status_value', 'text', ['type'=>'default']], - ['price', 'price_0_1', 'text', ['type'=>'default']], - ['position', 'position_category_1', 'text', ['type'=>'default']], - ['price', 'price_2_3', 'text', ['type'=>'default', 'customerGroupId'=>'2', 'websiteId'=>'3']], - ['position', 'position_category_3', 'text', ['type'=>'default', 'categoryId'=>'3']], - ['color', 'color_value', 'text', ['type'=>'text']], - ['description', 'sort_description', 'text', ['type'=>'some']], - ['*', '_all', 'text', ['type'=>'text']], - ['description', 'description_value', 'text', ['type'=>'text']], - ]; - } - - /** - * @return array - */ - public function attributeProvider() - { - return [ - [ - 'category_ids', - 'select', - ['searchable' => false, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => false], - ['category_ids' => ['type' => 'keyword'], 'category_ids_value' => ['type' => 'text']] - ], - [ - 'attr_code', - 'text', - ['searchable' => false, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => false], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'text', - ['searchable' => '0', 'filterable' => '0', 'filterableInSearch' => '0', 'advSearch' => '0'], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'text', - ['searchable' => true, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => false], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'text', - ['searchable' => '1', 'filterable' => '0', 'filterableInSearch' => '0', 'advSearch' => '0'], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'text', - ['searchable' => false, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => true], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'text', - ['searchable' => '0', 'filterable' => '0', 'filterableInSearch' => '1', 'advSearch' => '0'], - ['attr_code' => ['type' => 'integer']] - ], - ]; - } -} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php deleted file mode 100644 index 63c993e27c9a9..0000000000000 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldTypeTest.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter; - -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; -use PHPUnit_Framework_MockObject_MockObject as MockObject; - -class FieldTypeTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldType - */ - protected $type; - - /** - * @var \Magento\Eav\Model\Config|MockObject - */ - protected $eavConfig; - - /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute|\PHPUnit_Framework_MockObject_MockObject - */ - protected $eavAttributeResource; - - /** - * Set up test environment. - * - * @return void - */ - protected function setUp() - { - $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class) - ->disableOriginalConstructor() - ->setMethods(['getEntityType', 'getAttribute', 'getEntityAttributeCodes']) - ->getMock(); - - $objectManager = new ObjectManagerHelper($this); - - $this->eavAttributeResource = $this->createPartialMock( - \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class, - [ - '__wakeup', - 'getBackendType', - 'getFrontendInput' - ] - ); - - $this->type = $objectManager->getObject( - \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType::class, - [ - 'eavConfig' => $this->eavConfig, - ] - ); - } - - /** - * Test getFieldType() method. - * - * @dataProvider attributeTypesProvider - * @param string $attributeCode - * @param string $backendType - * @param string $frontendType - * @param string $expectedFieldType - * @return void - */ - public function testGetFieldType($attributeCode, $backendType, $frontendType, $expectedFieldType) - { - $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) - ->setMethods(['getBackendType', 'getFrontendInput', 'getAttributeCode']) - ->disableOriginalConstructor() - ->getMock(); - - $attributeMock->expects($this->any())->method('getBackendType') - ->will($this->returnValue($backendType)); - - $attributeMock->expects($this->any())->method('getFrontendInput') - ->will($this->returnValue($frontendType)); - - $attributeMock->expects($this->any())->method('getAttributeCode') - ->will($this->returnValue($attributeCode)); - - $this->assertEquals($expectedFieldType, $this->type->getFieldType($attributeMock)); - } - - /** - * @return array - */ - public static function attributeTypesProvider() - { - return [ - ['attr1', 'static', 'select', 'integer'], - ['attr1', 'static', 'text', 'text'], - ['attr1', 'timestamp', 'select', 'date'], - ['attr1', 'datetime', 'text', 'date'], - ['attr1', 'int', 'select', 'integer'], - ['attr1', 'decimal', 'text', 'float'], - ['attr1', 'varchar', 'select', 'text'], - ['attr1', 'array', 'multiselect', 'text'], - ['price', 'int', 'text', 'integer'], - ['tier_price', 'int', 'text', 'integer'], - ['tier_price', 'smallint', 'text', 'integer'], - ]; - } -} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php new file mode 100644 index 0000000000000..ccefb2c4844a7 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php @@ -0,0 +1,375 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\Model\AbstractExtensibleModel; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; + +class AttributeAdapterTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter + */ + private $adapter; + + /** + * @var AbstractExtensibleModel + */ + private $attribute; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->attribute = $this->getMockBuilder(AbstractExtensibleModel::class) + ->disableOriginalConstructor() + ->setMethods([ + 'getIsFilterable', + 'getIsFilterableInSearch', + 'getIsSearchable', + 'getIsVisibleInAdvancedSearch', + 'getBackendType', + 'getFrontendInput', + 'usesSource', + ]) + ->getMock(); + + $objectManager = new ObjectManagerHelper($this); + + $this->adapter = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter::class, + [ + 'attribute' => $this->attribute, + 'attributeCode' => 'code', + ] + ); + } + + /** + * @dataProvider isFilterableProvider + * @param $isFilterable + * @param $isFilterableInSearch + * @param $expected + * @return void + */ + public function testIsFilterable($isFilterable, $isFilterableInSearch, $expected) + { + $this->attribute + ->method('getIsFilterable') + ->willReturn($isFilterable); + $this->attribute + ->method('getIsFilterableInSearch') + ->willReturn($isFilterableInSearch); + $this->assertEquals( + $expected, + $this->adapter->isFilterable() + ); + } + + /** + * @dataProvider isSearchableProvider + * @param $isSearchable + * @param $isVisibleInAdvancedSearch + * @param $isFilterable + * @param $isFilterableInSearch + * @param $expected + * @return void + */ + public function testIsSearchable( + $isSearchable, + $isVisibleInAdvancedSearch, + $isFilterable, + $isFilterableInSearch, + $expected + ) { + $this->attribute + ->method('getIsSearchable') + ->willReturn($isSearchable); + $this->attribute + ->method('getIsVisibleInAdvancedSearch') + ->willReturn($isVisibleInAdvancedSearch); + $this->attribute + ->method('getIsFilterable') + ->willReturn($isFilterable); + $this->attribute + ->method('getIsFilterableInSearch') + ->willReturn($isFilterableInSearch); + $this->assertEquals( + $expected, + $this->adapter->isSearchable() + ); + } + + /** + * @dataProvider isAlwaysIndexableProvider + * @param $expected + * @return void + */ + public function testIsAlwaysIndexable($expected) { + $this->assertEquals( + $expected, + $this->adapter->isAlwaysIndexable() + ); + } + + /** + * @dataProvider isDateTimeTypeProvider + * @param $backendType + * @param $expected + * @return void + */ + public function testIsDateTimeType($backendType, $expected) { + $this->attribute + ->method('getBackendType') + ->willReturn($backendType); + $this->assertEquals( + $expected, + $this->adapter->isDateTimeType() + ); + } + + /** + * @dataProvider isFloatTypeProvider + * @param $backendType + * @param $expected + * @return void + */ + public function testIsFloatType($backendType, $expected) { + $this->attribute + ->method('getBackendType') + ->willReturn($backendType); + $this->assertEquals( + $expected, + $this->adapter->isFloatType() + ); + } + + /** + * @dataProvider isIntegerTypeProvider + * @param $backendType + * @param $expected + * @return void + */ + public function testIsIntegerType($backendType, $expected) { + $this->attribute + ->method('getBackendType') + ->willReturn($backendType); + $this->assertEquals( + $expected, + $this->adapter->isIntegerType() + ); + } + + /** + * @dataProvider isBooleanTypeProvider + * @param $frontendInput + * @param $backendType + * @param $expected + * @return void + */ + public function testIsBooleanType($frontendInput, $backendType, $expected) { + $this->attribute + ->method('getBackendType') + ->willReturn($backendType); + $this->attribute + ->method('getFrontendInput') + ->willReturn($frontendInput); + $this->assertEquals( + $expected, + $this->adapter->isBooleanType() + ); + } + + /** + * @dataProvider isComplexTypeProvider + * @param $frontendInput + * @param $usesSource + * @param $expected + * @return void + */ + public function testIsComplexType($frontendInput, $usesSource, $expected) { + $this->attribute + ->method('usesSource') + ->willReturn($usesSource); + $this->attribute + ->method('getFrontendInput') + ->willReturn($frontendInput); + $this->assertEquals( + $expected, + $this->adapter->isComplexType() + ); + } + + /** + * @dataProvider isEavAttributeProvider + * @param $expected + * @return void + */ + public function testIsEavAttribute($expected) { + $this->assertEquals( + $expected, + $this->adapter->isEavAttribute() + ); + } + + /** + * @return array + */ + public function isEavAttributeProvider() + { + return [ + [false], + ]; + } + + /** + * @return array + */ + public function isComplexTypeProvider() + { + return [ + ['select', true, true], + ['multiselect', true, true], + ['multiselect', false, true], + ['int', false, false], + ['int', true, true], + ]; + } + + /** + * @return array + */ + public function isBooleanTypeProvider() + { + return [ + ['select', 'int', true], + ['boolean', 'int', true], + ['boolean', 'varchar', false], + ['select', 'varchar', false], + ['int', 'varchar', false], + ['int', 'int', false], + ]; + } + + /** + * @return array + */ + public function isIntegerTypeProvider() + { + return [ + ['smallint', true], + ['int', true], + ['string', false], + ]; + } + + /** + * @return array + */ + public function isFloatTypeProvider() + { + return [ + ['decimal', true], + ['int', false], + ]; + } + + /** + * @return array + */ + public function isDateTimeTypeProvider() + { + return [ + ['timestamp', true], + ['datetime', true], + ['int', false], + ]; + } + + /** + * @return array + */ + public function isAlwaysIndexableProvider() + { + return [ + [false] + ]; + } + + /** + * @return array + */ + public function isSearchableProvider() + { + return [ + [true, false, false, false, true], + [false, false, false, false, false], + [false, true, false, false, true], + [false, false, true, false, true], + [true, true, true, false, true], + [true, true, false, false, true], + ]; + } + + /** + * @return array + */ + public function isFilterableProvider() + { + return [ + [true, false, true,], + [true, false, true,], + [false, false, false,] + ]; + } + + /** + * @return array + */ + public function isStringServiceFieldTypeProvider() + { + return [ + ['string', 'text', false,], + ['text', 'text', true,] + ]; + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['name', [], 'name'] + ]; + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + ['type', 'type'] + ]; + } + + /** + * @return array + */ + public function getFieldIndexProvider() + { + return [ + ['type', 'no', 'no'] + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php new file mode 100644 index 0000000000000..4907c89d35aaa --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php @@ -0,0 +1,327 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider; + +use Magento\Framework\Api\SearchCriteria; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Catalog\Api\CategoryListInterface; +use Magento\Customer\Api\GroupRepositoryInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface + as IndexTypeConverterInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Catalog\Api\Data\CategorySearchResultsInterface; +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Customer\Api\Data\GroupSearchResultsInterface; +use Magento\Customer\Api\Data\GroupInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface + as FieldNameResolver; + +class DynamicFieldTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\DynamicField + */ + private $provider; + + /** + * @var GroupRepositoryInterface + */ + private $groupRepository; + + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var IndexTypeConverterInterface + */ + private $indexTypeConverter; + + /** + * @var AttributeProvider + */ + private $attributeAdapterProvider; + + /** + * @var CategoryListInterface + */ + private $categoryList; + + /** + * @var FieldNameResolver + */ + private $fieldNameResolver; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->groupRepository = $this->getMockBuilder(GroupRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->searchCriteriaBuilder = $this->getMockBuilder(SearchCriteriaBuilder::class) + ->disableOriginalConstructor() + ->getMock(); + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->indexTypeConverter = $this->getMockBuilder(IndexTypeConverterInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->attributeAdapterProvider = $this->getMockBuilder(AttributeProvider::class) + ->disableOriginalConstructor() + ->setMethods(['getByAttributeCode', 'getByAttribute']) + ->getMock(); + $this->fieldNameResolver = $this->getMockBuilder(FieldNameResolver::class) + ->disableOriginalConstructor() + ->setMethods(['getFieldName']) + ->getMock(); + $this->categoryList = $this->getMockBuilder(CategoryListInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $objectManager = new ObjectManagerHelper($this); + + $this->provider = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\DynamicField::class, + [ + 'groupRepository' => $this->groupRepository, + 'searchCriteriaBuilder' => $this->searchCriteriaBuilder, + 'fieldTypeConverter' => $this->fieldTypeConverter, + 'indexTypeConverter' => $this->indexTypeConverter, + 'attributeAdapterProvider' => $this->attributeAdapterProvider, + 'categoryList' => $this->categoryList, + 'fieldNameResolver' => $this->fieldNameResolver, + ] + ); + } + + /** + * @dataProvider attributeProvider + * @param $complexType + * @param $categoryId + * @param $groupId + * @param array $expected + * @return void + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function testGetAllAttributesTypes( + $complexType, + $categoryId, + $groupId, + $expected + ) { + $searchCriteria = $this->getMockBuilder(SearchCriteria::class) + ->disableOriginalConstructor() + ->getMock(); + $this->searchCriteriaBuilder->expects($this->any()) + ->method('create') + ->willReturn($searchCriteria); + $categorySearchResults = $this->getMockBuilder(CategorySearchResultsInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getItems']) + ->getMockForAbstractClass(); + $groupSearchResults = $this->getMockBuilder(GroupSearchResultsInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getItems']) + ->getMockForAbstractClass(); + $group = $this->getMockBuilder(GroupInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getId']) + ->getMockForAbstractClass(); + $group->expects($this->any()) + ->method('getId') + ->willReturn($groupId); + $groupSearchResults->expects($this->any()) + ->method('getItems') + ->willReturn([$group]); + $category = $this->getMockBuilder(CategoryInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getId']) + ->getMockForAbstractClass(); + $category->expects($this->any()) + ->method('getId') + ->willReturn($categoryId); + $categorySearchResults->expects($this->any()) + ->method('getItems') + ->willReturn([$category]); + $this->categoryList->expects($this->any()) + ->method('getList') + ->willReturn($categorySearchResults); + + $categoryAttributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $categoryAttributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn('category'); + $positionAttributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $positionAttributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn('position'); + + $this->fieldNameResolver->expects($this->any()) + ->method('getFieldName') + ->will($this->returnCallback( + function($attribute)use ($categoryId) { + static $callCount = array(); + $attributeCode = $attribute->getAttributeCode(); + $callCount[$attributeCode] = !isset($callCount[$attributeCode]) ? 1 : ++$callCount[$attributeCode]; + + if ($attributeCode === 'category') { + return 'category_name_' . $categoryId; + } elseif ($attributeCode === 'position') { + return 'position_' . $categoryId; + } elseif ($attributeCode === 'price') { + return 'price_' . $categoryId . '_1'; + } + } + )); + $priceAttributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $priceAttributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn('price'); + $this->indexTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('no_index'); + $this->groupRepository->expects($this->any()) + ->method('getList') + ->willReturn($groupSearchResults); + $this->attributeAdapterProvider->expects($this->any()) + ->method('getByAttributeCode') + ->with($this->anything()) + ->will($this->returnCallback( + function($code) use( + $categoryAttributeMock, + $positionAttributeMock, + $priceAttributeMock + ) { + static $callCount = array(); + $callCount[$code] = !isset($callCount[$code]) ? 1 : ++$callCount[$code]; + + if ($code === 'position') { + return $positionAttributeMock; + } elseif ($code === 'category_name') { + return $categoryAttributeMock; + } elseif ($code === 'price') { + return $priceAttributeMock; + } + } + )); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->with($this->anything()) + ->will($this->returnCallback( + function($type) use ($complexType) { + static $callCount = array(); + $callCount[$type] = !isset($callCount[$type]) ? 1 : ++$callCount[$type]; + + if ($type === 'string') { + return 'string'; + } if ($type === 'string') { + return 'string'; + } elseif($type === 'float') { + return 'float'; + } else { + return $complexType; + } + } + )); + + + $this->assertEquals( + $expected, + $this->provider->getFields(['storeId' => 1]) + ); + } + + /** + * @return array + */ + public function attributeProvider() + { + return [ + [ + 'text', + 1, + 1, + [ + 'category_name_1' => [ + 'type' => 'string', + 'index' => 'no_index' + ], + 'position_1' => [ + 'type' => 'string', + 'index' => 'no_index' + ], + 'price_1_1' => [ + 'type' => 'float', + 'store' => true + ] + ] + ], + [ + null, + 1, + 1, + [ + 'category_name_1' => [ + 'type' => 'string', + 'index' => 'no_index' + ], + 'position_1' => [ + 'type' => 'string', + 'index' => 'no_index' + ], + 'price_1_1' => [ + 'type' => 'float', + 'store' => true + ] + ], + ], + [ + null, + 1, + 1, + [ + 'category_name_1' => [ + 'type' => 'string', + 'index' => 'no_index' + ], + 'position_1' => [ + 'type' => 'string', + 'index' => 'no_index' + ], + 'price_1_1' => [ + 'type' => 'float', + 'store' => true + ] + ] + ] + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php new file mode 100644 index 0000000000000..497f3d957e181 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php @@ -0,0 +1,95 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class IndexResolverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver + */ + private $resolver; + + /** + * @var ConverterInterface + */ + private $converter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->converter = $this->getMockBuilder(ConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver::class, + [ + 'converter' => $this->converter + ] + ); + } + + /** + * @dataProvider getFieldIndexProvider + * @param $isSearchable + * @param $isAlwaysIndexable + * @param $serviceFieldType + * @param $expected + * @return void + */ + public function testGetFieldName( + $isSearchable, + $isAlwaysIndexable, + $serviceFieldType, + $expected + ) { + $this->converter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods([ + 'isSearchable', + 'isAlwaysIndexable', + ]) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isSearchable') + ->willReturn($isSearchable); + $attributeMock->expects($this->any()) + ->method('isAlwaysIndexable') + ->willReturn($isAlwaysIndexable); + + $this->assertEquals( + $expected, + $this->resolver->getFieldIndex($attributeMock, $serviceFieldType) + ); + } + + /** + * @return array + */ + public function getFieldIndexProvider() + { + return [ + [true, true, 'string', null], + [false, false, 'string', 'something'], + [true, false, 'string', null], + [false, true, 'string', null], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php new file mode 100644 index 0000000000000..9944874b97a92 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php @@ -0,0 +1,119 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Store\Api\Data\StoreInterface; + +class CategoryNameTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName + */ + private $resolver; + + /** + * @var StoreManager + */ + private $storeManager; + + /** + * @var Registry + */ + private $coreRegistry; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->storeManager = $this->getMockBuilder(StoreManager::class) + ->disableOriginalConstructor() + ->setMethods(['getStore']) + ->getMockForAbstractClass(); + $this->coreRegistry = $this->getMockBuilder(Registry::class) + ->disableOriginalConstructor() + ->setMethods(['registry']) + ->getMock(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName::class, + [ + 'storeManager' => $this->storeManager, + 'coreRegistry' => $this->coreRegistry, + ] + ); + } + + /** + * @dataProvider getFieldNameProvider + * @param $attributeCode + * @param $context + * @param $fromRegistry + * @param $expected + * @return void + */ + public function testGetFieldName($attributeCode, $context, $fromRegistry, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $store = $this->getMockBuilder(StoreInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getRootCategoryId']) + ->getMockForAbstractClass(); + $store->expects($this->any()) + ->method('getRootCategoryId') + ->willReturn(2); + $this->storeManager->expects($this->any()) + ->method('getStore') + ->willReturn($store); + $category = null; + if ($fromRegistry) { + $category = $this->getMockBuilder(CategoryInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getId']) + ->getMockForAbstractClass(); + $category->expects($this->any()) + ->method('getId') + ->willReturn(1); + } + $this->coreRegistry->expects($this->any()) + ->method('registry') + ->willReturn($category); + + $this->assertEquals( + $expected, + $this->resolver->getFieldName($attributeMock, $context) + ); + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['category_name', [], true, 'name_category_1'], + ['category_name', [], false, 'name_category_2'], + ['category_name', ['categoryId' => 3], false, 'name_category_3'], + ['price', ['categoryId' => 3], false, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php new file mode 100644 index 0000000000000..2fe75d46eb36b --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php @@ -0,0 +1,113 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface + as FieldTypeResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; + +class DefaultResolverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver + */ + private $resolver; + + /** + * @var FieldTypeResolver + */ + private $fieldTypeResolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $objectManager = new ObjectManagerHelper($this); + $this->fieldTypeResolver = $this->getMockBuilder(FieldTypeResolver::class) + ->disableOriginalConstructor() + ->setMethods(['getFieldType']) + ->getMockForAbstractClass(); + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver::class, + [ + 'fieldTypeResolver' => $this->fieldTypeResolver, + 'fieldTypeConverter' => $this->fieldTypeConverter + ] + ); + } + + /** + * @dataProvider getFieldNameProvider + * @param $fieldType + * @param $attributeCode + * @param $frontendInput + * @param $context + * @param $expected + * @return void + */ + public function testGetFieldName( + $fieldType, + $attributeCode, + $frontendInput, + $context, + $expected + ) { + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('string'); + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode', 'getFrontendInput']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $attributeMock->expects($this->any()) + ->method('getFrontendInput') + ->willReturn($frontendInput); + $this->fieldTypeResolver->expects($this->any()) + ->method('getFieldType') + ->willReturn($fieldType); + + $this->assertEquals( + $expected, + $this->resolver->getFieldName($attributeMock, $context) + ); + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['', 'code', '', [], 'code'], + ['', 'code', '', ['type' => 'default'], 'code'], + ['string', '*', '', ['type' => 'default'], '_all'], + ['', 'code', '', ['type' => 'default'], 'code'], + ['', 'code', 'select', ['type' => 'default'], 'code'], + ['', 'code', 'boolean', ['type' => 'default'], 'code'], + ['', 'code', '', ['type' => 'type'], 'sort_code'], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php new file mode 100644 index 0000000000000..c76bb8661d761 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php @@ -0,0 +1,74 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Store\Api\Data\StoreInterface; + +class NotEavAttributeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute + */ + private $resolver; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute::class + ); + } + + /** + * @dataProvider getFieldNameProvider + * @param $attributeCode + * @param $isEavAttribute + * @param $context + * @param $expected + * @return void + */ + public function testGetFieldName($attributeCode, $isEavAttribute, $context, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['isEavAttribute', 'getAttributeCode']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isEavAttribute') + ->willReturn($isEavAttribute); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + + $this->assertEquals( + $expected, + $this->resolver->getFieldName($attributeMock, $context) + ); + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['code', true, [], ''], + ['code', false, [], 'code'], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php new file mode 100644 index 0000000000000..d1d6bb5a91c22 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php @@ -0,0 +1,119 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\Registry; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Store\Api\Data\StoreInterface; + +class PositionTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position + */ + private $resolver; + + /** + * @var StoreManager + */ + private $storeManager; + + /** + * @var Registry + */ + private $coreRegistry; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->storeManager = $this->getMockBuilder(StoreManager::class) + ->disableOriginalConstructor() + ->setMethods(['getStore']) + ->getMockForAbstractClass(); + $this->coreRegistry = $this->getMockBuilder(Registry::class) + ->disableOriginalConstructor() + ->setMethods(['registry']) + ->getMock(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position::class, + [ + 'storeManager' => $this->storeManager, + 'coreRegistry' => $this->coreRegistry, + ] + ); + } + + /** + * @dataProvider getFieldNameProvider + * @param $attributeCode + * @param $context + * @param $fromRegistry + * @param $expected + * @return void + */ + public function testGetFieldName($attributeCode, $context, $fromRegistry, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $store = $this->getMockBuilder(StoreInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getRootCategoryId']) + ->getMockForAbstractClass(); + $store->expects($this->any()) + ->method('getRootCategoryId') + ->willReturn(2); + $this->storeManager->expects($this->any()) + ->method('getStore') + ->willReturn($store); + $category = null; + if ($fromRegistry) { + $category = $this->getMockBuilder(CategoryInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getId']) + ->getMockForAbstractClass(); + $category->expects($this->any()) + ->method('getId') + ->willReturn(1); + } + $this->coreRegistry->expects($this->any()) + ->method('registry') + ->willReturn($category); + + $this->assertEquals( + $expected, + $this->resolver->getFieldName($attributeMock, $context) + ); + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['position', [], true, 'position_category_1'], + ['position', [], false, 'position_category_2'], + ['position', ['categoryId' => 2], false, 'position_category_2'], + ['price', ['categoryId' => 2], false, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php new file mode 100644 index 0000000000000..649244fd2a33c --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php @@ -0,0 +1,107 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Store\Model\StoreManagerInterface as StoreManager; +use Magento\Store\Api\Data\StoreInterface; + +class PriceTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price + */ + private $resolver; + + /** + * @var CustomerSession + */ + private $customerSession; + + /** + * @var StoreManager + */ + private $storeManager; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->customerSession = $this->getMockBuilder(CustomerSession::class) + ->disableOriginalConstructor() + ->setMethods(['getCustomerGroupId']) + ->getMock(); + $this->storeManager = $this->getMockBuilder(StoreManager::class) + ->disableOriginalConstructor() + ->setMethods(['getStore']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price::class, + [ + 'customerSession' => $this->customerSession, + 'storeManager' => $this->storeManager, + ] + ); + } + + /** + * @dataProvider getFieldNameProvider + * @param $attributeCode + * @param $context + * @param $expected + * @return void + */ + public function testGetFieldName($attributeCode, $context, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $this->customerSession->expects($this->any()) + ->method('getCustomerGroupId') + ->willReturn(1); + $store = $this->getMockBuilder(StoreInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getWebsiteId']) + ->getMockForAbstractClass(); + $store->expects($this->any()) + ->method('getWebsiteId') + ->willReturn(2); + $this->storeManager->expects($this->any()) + ->method('getStore') + ->willReturn($store); + + $this->assertEquals( + $expected, + $this->resolver->getFieldName($attributeMock, $context) + ); + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['price', [], 'price_1_2'], + ['price', ['customerGroupId' => 2, 'websiteId' => 3], 'price_2_3'], + ['price', ['customerGroupId' => 2], 'price_2_2'], + ['sku', ['customerGroupId' => 2], ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php new file mode 100644 index 0000000000000..849bf0e35bf48 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php @@ -0,0 +1,68 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class SpecialAttributeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute + */ + private $resolver; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute::class + ); + } + + /** + * @dataProvider getFieldNameProvider + * @param $attributeCode + * @param $expected + * @return void + */ + public function testGetFieldName($attributeCode, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + + $this->assertEquals( + $expected, + $this->resolver->getFieldName($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldNameProvider() + { + return [ + ['id', 'id'], + ['sku', 'sku'], + ['store_id', 'store_id'], + ['visibility', 'visibility'], + ['price', ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php new file mode 100644 index 0000000000000..eec577988d046 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\FieldProvider\Product\FieldType; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Psr\Log\LoggerInterface; + +class ConverterTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter + */ + private $converter; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->logger = $this->getMockBuilder(LoggerInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->converter = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter::class, + [ + 'logger' => $this->logger, + ] + ); + } + + /** + * @dataProvider convertProvider + * @param $internalType + * @param $expected + * @return void + */ + public function testConvert($internalType, $expected) + { + $this->assertEquals( + $expected, + $this->converter->convert($internalType) + ); + } + + /** + * @return array + */ + public function convertProvider() + { + return [ + ['string', 'string'], + ['float', 'float'], + ['integer', 'integer'], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php new file mode 100644 index 0000000000000..43eff23702aa7 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php @@ -0,0 +1,83 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class DateTimeTypeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType + */ + private $resolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType::class, + [ + 'fieldTypeConverter' => $this->fieldTypeConverter, + ] + ); + } + + /** + * @dataProvider getFieldTypeProvider + * @param $isDateTimeType + * @param $expected + * @return void + */ + public function testGetFieldType($isDateTimeType, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['isDateTimeType']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isDateTimeType') + ->willReturn($isDateTimeType); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + + $this->assertEquals( + $expected, + $this->resolver->getFieldType($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + [true, 'something'], + [false, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php new file mode 100644 index 0000000000000..983a1b941a2c3 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class DefaultResolverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver + */ + private $resolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver::class, + [ + 'fieldTypeConverter' => $this->fieldTypeConverter, + ] + ); + } + + /** + * @dataProvider getFieldTypeProvider + * @param $expected + * @return void + */ + public function testGetFieldType($expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->getMock(); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + + $this->assertEquals( + $expected, + $this->resolver->getFieldType($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + ['something'], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php new file mode 100644 index 0000000000000..757d830bb49b3 --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php @@ -0,0 +1,83 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class FloatTypeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\FloatType + */ + private $resolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\FloatType::class, + [ + 'fieldTypeConverter' => $this->fieldTypeConverter, + ] + ); + } + + /** + * @dataProvider getFieldTypeProvider + * @param $isFloatType + * @param $expected + * @return void + */ + public function testGetFieldType($isFloatType, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['isFloatType']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isFloatType') + ->willReturn($isFloatType); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + + $this->assertEquals( + $expected, + $this->resolver->getFieldType($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + [true, 'something'], + [false, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php new file mode 100644 index 0000000000000..bd88b4bcc8a1b --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; + +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class IntegerTypeTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType + */ + private $resolver; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->setMethods(['convert']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManagerHelper($this); + + $this->resolver = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType::class, + [ + 'fieldTypeConverter' => $this->fieldTypeConverter, + ] + ); + } + + /** + * @dataProvider getFieldTypeProvider + * @param $attributeCode + * @param $isIntegerType + * @param $isBooleanType + * @param $isUserDefined + * @param $expected + * @return void + */ + public function testGetFieldType($attributeCode, $isIntegerType, $isBooleanType, $isUserDefined, $expected) + { + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode', 'isIntegerType', 'isBooleanType', 'isUserDefined']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $attributeMock->expects($this->any()) + ->method('isIntegerType') + ->willReturn($isIntegerType); + $attributeMock->expects($this->any()) + ->method('isBooleanType') + ->willReturn($isBooleanType); + $attributeMock->expects($this->any()) + ->method('isUserDefined') + ->willReturn($isUserDefined); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('something'); + + $this->assertEquals( + $expected, + $this->resolver->getFieldType($attributeMock) + ); + } + + /** + * @return array + */ + public function getFieldTypeProvider() + { + return [ + ['category_ids', true, true, true, null], + ['category_ids', false, false, false, null], + ['type', true, false, false, 'something'], + ['type', false, true, false, 'something'], + ['type', true, true, true, ''], + ['type', false, false, true, ''], + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php new file mode 100644 index 0000000000000..1efc31ac0942f --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php @@ -0,0 +1,245 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider; + +use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Eav\Model\Config; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface + as IndexTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface + as FieldTypeResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ResolverInterface + as FieldIndexResolver; + +class StaticFieldTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\StaticField + */ + private $provider; + + /** + * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject + */ + private $eavConfig; + + /** + * @var FieldTypeConverterInterface + */ + private $fieldTypeConverter; + + /** + * @var IndexTypeConverterInterface + */ + private $indexTypeConverter; + + /** + * @var AttributeProvider + */ + private $attributeAdapterProvider; + + /** + * @var FieldIndexResolver + */ + private $fieldIndexResolver; + + /** + * @var FieldTypeResolver + */ + private $fieldTypeResolver; + + /** + * Set up test environment + * + * @return void + */ + protected function setUp() + { + $this->eavConfig = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->setMethods(['getEntityAttributes']) + ->getMock(); + $this->fieldTypeConverter = $this->getMockBuilder(FieldTypeConverterInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->indexTypeConverter = $this->getMockBuilder(IndexTypeConverterInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->attributeAdapterProvider = $this->getMockBuilder(AttributeProvider::class) + ->disableOriginalConstructor() + ->setMethods(['getByAttributeCode']) + ->getMock(); + $this->fieldTypeResolver = $this->getMockBuilder(FieldTypeResolver::class) + ->disableOriginalConstructor() + ->setMethods(['getFieldType']) + ->getMock(); + $this->fieldIndexResolver = $this->getMockBuilder(FieldIndexResolver::class) + ->disableOriginalConstructor() + ->setMethods(['getFieldIndex']) + ->getMock(); + + $objectManager = new ObjectManagerHelper($this); + + $this->provider = $objectManager->getObject( + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\StaticField::class, + [ + 'eavConfig' => $this->eavConfig, + 'fieldTypeConverter' => $this->fieldTypeConverter, + 'indexTypeConverter' => $this->indexTypeConverter, + 'attributeAdapterProvider' => $this->attributeAdapterProvider, + 'fieldIndexResolver' => $this->fieldIndexResolver, + 'fieldTypeResolver' => $this->fieldTypeResolver, + ] + ); + } + + /** + * @dataProvider attributeProvider + * @param string $attributeCode + * @param string $inputType + * @param $indexType + * @param $isComplexType + * @param $complexType + * @param array $expected + * @return void + */ + public function testGetAllAttributesTypes( + $attributeCode, + $inputType, + $indexType, + $isComplexType, + $complexType, + $expected + ) { + $this->fieldTypeResolver->expects($this->any()) + ->method('getFieldType') + ->willReturn($inputType); + $this->fieldIndexResolver->expects($this->any()) + ->method('getFieldIndex') + ->willReturn($indexType); + $this->indexTypeConverter->expects($this->any()) + ->method('convert') + ->willReturn('no'); + + $productAttributeMock = $this->getMockBuilder(AbstractAttribute::class) + ->setMethods(['getAttributeCode']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $productAttributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $this->eavConfig->expects($this->any())->method('getEntityAttributes') + ->willReturn([$productAttributeMock]); + + $attributeMock = $this->getMockBuilder(AttributeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['isComplexType', 'getAttributeCode']) + ->getMock(); + $attributeMock->expects($this->any()) + ->method('isComplexType') + ->willReturn($isComplexType); + $attributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $this->attributeAdapterProvider->expects($this->any()) + ->method('getByAttributeCode') + ->with($this->anything()) + ->willReturn($attributeMock); + $this->fieldTypeConverter->expects($this->any()) + ->method('convert') + ->with($this->anything()) + ->will($this->returnCallback( + function($type) use ($complexType) { + static $callCount = array(); + $callCount[$type] = !isset($callCount[$type]) ? 1 : ++$callCount[$type]; + + if ($type === 'string') { + return 'string'; + } if ($type === 'string') { + return 'string'; + } elseif($type === 'float') { + return 'float'; + } else { + return $complexType; + } + } + )); + + + $this->assertEquals( + $expected, + $this->provider->getFields(['storeId' => 1]) + ); + } + + /** + * @return array + */ + public function attributeProvider() + { + return [ + [ + 'category_ids', + 'select', + true, + true, + 'text', + [ + 'category_ids' => [ + 'type' => 'select', + 'index' => true + ], + 'category_ids_value' => [ + 'type' => 'string' + ], + 'store_id' => [ + 'type' => 'string', + 'index' => 'no' + ] + ] + ], + [ + 'attr_code', + 'text', + 'no', + false, + null, + [ + 'attr_code' => [ + 'type' => 'text', + 'index' => 'no' + ], + 'store_id' => [ + 'type' => 'string', + 'index' => 'no' + ] + ], + ], + [ + 'attr_code', + 'text', + null, + false, + null, + [ + 'attr_code' => [ + 'type' => 'text' + ], + 'store_id' => [ + 'type' => 'string', + 'index' => 'no' + ] + ] + ] + ]; + } +} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/ProductFieldMapperTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/ProductFieldMapperTest.php deleted file mode 100644 index 8b7ac6abbb190..0000000000000 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/ProductFieldMapperTest.php +++ /dev/null @@ -1,298 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper; - -use Magento\Catalog\Api\Data\ProductAttributeInterface; -use Magento\Elasticsearch\Model\Adapter\FieldType; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; - -class ProductFieldMapperTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\ProductFieldMapper - */ - protected $mapper; - - /** - * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject - */ - protected $eavConfig; - - /** - * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject - */ - protected $coreRegistry; - - /** - * @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject - */ - protected $customerSession; - - /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $storeManager; - - /** - * @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute|\PHPUnit_Framework_MockObject_MockObject - */ - protected $eavAttributeResource; - - /** - * @var FieldType|\PHPUnit_Framework_MockObject_MockObject - */ - protected $fieldType; - - /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $store; - - /** - * Set up test environment - * - * @return void - */ - protected function setUp() - { - $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class) - ->disableOriginalConstructor() - ->setMethods(['getEntityType', 'getAttribute', 'getEntityAttributeCodes']) - ->getMock(); - - $this->fieldType = $this->getMockBuilder(FieldType::class) - ->disableOriginalConstructor() - ->setMethods(['getFieldType']) - ->getMock(); - - $this->customerSession = $this->getMockBuilder(\Magento\Customer\Model\Session::class) - ->disableOriginalConstructor() - ->setMethods(['getCustomerGroupId']) - ->getMock(); - - $this->storeManager = $this->storeManager = $this->getMockForAbstractClass( - \Magento\Store\Model\StoreManagerInterface::class, - [], - '', - false - ); - - $this->store = $this->getMockForAbstractClass( - \Magento\Store\Api\Data\StoreInterface::class, - [], - '', - false, - false, - true, - ['getWebsiteId', 'getRootCategoryId'] - ); - - $this->coreRegistry = $this->createMock(\Magento\Framework\Registry::class); - - $objectManager = new ObjectManagerHelper($this); - - $this->eavAttributeResource = $this->createPartialMock( - \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class, - [ - '__wakeup', - 'getBackendType', - 'getFrontendInput' - ] - ); - - $this->mapper = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\ProductFieldMapper::class, - [ - 'eavConfig' => $this->eavConfig, - 'storeManager' => $this->storeManager, - 'fieldType' => $this->fieldType, - 'customerSession' => $this->customerSession, - 'coreRegistry' => $this->coreRegistry - ] - ); - } - - /** - * @dataProvider attributeCodeProvider - * @param string $attributeCode - * @param string $fieldName - * @param string $fieldType - * @param array $context - * - * @return void - */ - public function testGetFieldName($attributeCode, $fieldName, $fieldType, $context = []) - { - $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) - ->setMethods(['getBackendType', 'getFrontendInput', 'getAttribute']) - ->disableOriginalConstructor() - ->getMock(); - - $this->customerSession->expects($this->any()) - ->method('getCustomerGroupId') - ->willReturn('0'); - - $this->storeManager->expects($this->any()) - ->method('getStore') - ->willReturn($this->store); - $this->store->expects($this->any()) - ->method('getWebsiteId') - ->willReturn('1'); - $this->store->expects($this->any()) - ->method('getRootCategoryId') - ->willReturn('1'); - - $this->eavConfig->expects($this->any())->method('getAttribute') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode) - ->willReturn($attributeMock); - - $attributeMock->expects($this->any())->method('getFrontendInput') - ->will($this->returnValue('select')); - - $this->fieldType->expects($this->any())->method('getFieldType') - ->with($attributeMock) - ->willReturn($fieldType); - - $this->assertEquals( - $fieldName, - $this->mapper->getFieldName($attributeCode, $context) - ); - } - - /** - * @return void - */ - public function testGetFieldNameWithoutAttribute() - { - $this->eavConfig->expects($this->any())->method('getAttribute') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, 'attr1') - ->willReturn(''); - - $this->assertEquals( - 'attr1', - $this->mapper->getFieldName('attr1', []) - ); - } - - /** - * @dataProvider attributeProvider - * @param string $attributeCode - * @param string $inputType - * @param array $searchAttributes - * @param array $expected - * @return void - */ - public function testGetAllAttributesTypes($attributeCode, $inputType, $searchAttributes, $expected) - { - $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->eavConfig->expects($this->any())->method('getEntityAttributeCodes') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE) - ->willReturn([$attributeCode]); - - $this->eavConfig->expects($this->any())->method('getAttribute') - ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode) - ->willReturn($attributeMock); - - $this->fieldType->expects($this->once())->method('getFieldType')->willReturn(FieldType::ES_DATA_TYPE_INT); - - $attributeMock->expects($this->any()) - ->method('getIsSearchable') - ->willReturn($searchAttributes['searchable']); - $attributeMock->expects($this->any()) - ->method('getIsFilterable') - ->willReturn($searchAttributes['filterable']); - $attributeMock->expects($this->any()) - ->method('getIsFilterableInSearch') - ->willReturn($searchAttributes['filterableInSearch']); - $attributeMock->expects($this->any()) - ->method('getIsVisibleInAdvancedSearch') - ->willReturn($searchAttributes['advSearch']); - - $attributeMock->expects($this->any())->method('getFrontendInput') - ->will($this->returnValue($inputType)); - - $this->assertEquals( - $expected, - $this->mapper->getAllAttributesTypes() - ); - } - - /** - * @return array - */ - public function attributeCodeProvider() - { - return [ - ['id', 'id', 'string'], - ['status', 'status', 'string'], - ['status', 'status_value', 'string', ['type'=>'default']], - ['price', 'price_0_1', 'string', ['type'=>'default']], - ['position', 'position_category_1', 'string', ['type'=>'default']], - ['price', 'price_2_3', 'string', ['type'=>'default', 'customerGroupId'=>'2', 'websiteId'=>'3']], - ['position', 'position_category_3', 'string', ['type'=>'default', 'categoryId'=>'3']], - ['color', 'color_value', 'string', ['type'=>'text']], - ['description', 'sort_description', 'string', ['type'=>'some']], - ['*', '_all', 'string', ['type'=>'text']], - ['description', 'description_value', 'string', ['type'=>'text']], - ]; - } - - /** - * @return array - */ - public function attributeProvider() - { - return [ - [ - 'category_ids', - 'text', - ['searchable' => false, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => false], - ['category_ids' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'string', - ['searchable' => false, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => false], - ['attr_code' => ['type' => 'integer', 'index' => 'no']] - ], - [ - 'attr_code', - 'string', - ['searchable' => '0', 'filterable' => '0', 'filterableInSearch' => '0', 'advSearch' => '0'], - ['attr_code' => ['type' => 'integer', 'index' => 'no']] - ], - [ - 'attr_code', - 'string', - ['searchable' => true, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => false], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'string', - ['searchable' => '1', 'filterable' => '0', 'filterableInSearch' => '0', 'advSearch' => '0'], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'string', - ['searchable' => false, 'filterable' => false, 'filterableInSearch' => false, 'advSearch' => true], - ['attr_code' => ['type' => 'integer']] - ], - [ - 'attr_code', - 'string', - ['searchable' => '0', 'filterable' => '0', 'filterableInSearch' => '1', 'advSearch' => '0'], - ['attr_code' => ['type' => 'integer']] - ], - ]; - } -} diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index 18772756b12a2..8e39e048cfba6 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -7,7 +7,12 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapperInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver" /> - <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\ResolverInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\NotEavAttribute" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ResolverInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\Converter" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter" /> + <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\CompositeFieldProvider" /> <type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver"> <arguments> <argument name="fieldMappers" xsi:type="array"> @@ -272,29 +277,139 @@ </argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\NotEavAttribute"> + <type name="Magento\Elasticsearch\Elasticsearch5\Model\Adapter\BatchDataMapper\CategoryFieldsProvider"> <arguments> - <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\SpecialAttribute</argument> + <argument name="fieldNameResolver" xsi:type="object">elasticsearch5FieldNameResolver</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\SpecialAttribute"> + <type name="Magento\Elasticsearch\Elasticsearch5\Model\Adapter\DataMapper\ProductDataMapper"> <arguments> - <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Price</argument> + <argument name="fieldNameResolver" xsi:type="object">elasticsearch5FieldNameResolver</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Price"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver"> <arguments> - <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\CategoryName</argument> + <argument name="items" xsi:type="array"> + <item name="notEav" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute</item> + <item name="special" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute</item> + <item name="price" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price</item> + <item name="categoryName" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName</item> + <item name="position" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position</item> + <item name="default" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver</item> + </argument> + </arguments> + </type> + <virtualType name="elasticsearch5FieldNameResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver"> + <arguments> + <argument name="items" xsi:type="array"> + <item name="notEav" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute</item> + <item name="special" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute</item> + <item name="price" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price</item> + <item name="categoryName" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName</item> + <item name="position" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position</item> + <item name="default" xsi:type="object">elasticsearch5FieldNameDefaultResolver</item> + </argument> + </arguments> + </virtualType> + <virtualType name="elasticsearch5FieldNameDefaultResolver" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver"> + <arguments> + <argument name="fieldTypeResolver" xsi:type="object">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver</argument> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + </arguments> + </virtualType> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver"> + <arguments> + <argument name="items" xsi:type="array"> + <item name="integer" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType</item> + <item name="datetime" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType</item> + <item name="float" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\FloatType</item> + <item name="default" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver</item> + </argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver"> + <arguments> + <argument name="items" xsi:type="array"> + <item name="keyword" xsi:type="object">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType</item> + <item name="integer" xsi:type="object">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType</item> + <item name="datetime" xsi:type="object">elasticsearch5FieldTypeDateTimeResolver</item> + <item name="float" xsi:type="object">elasticsearch5FieldTypeFloatResolver</item> + <item name="default" xsi:type="object">elasticsearch5FieldTypeDefaultResolver</item> + </argument> + </arguments> + </type> + <type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\CompositeFieldProvider"> + <arguments> + <argument name="providers" xsi:type="array"> + <item name="static" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\StaticField</item> + <item name="dynamic" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\DynamicField</item> + </argument> + </arguments> + </type> + <virtualType name="elasticsearch5FieldProvider" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\CompositeFieldProvider"> + <arguments> + <argument name="providers" xsi:type="array"> + <item name="static" xsi:type="object">elasticsearch5StaticFieldProvider</item> + <item name="dynamic" xsi:type="object">elasticsearch5DynamicFieldProvider</item> + </argument> + </arguments> + </virtualType> + <virtualType name="elasticsearch5StaticFieldProvider" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\StaticField"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + <argument name="indexTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\Converter</argument> + <argument name="fieldIndexResolver" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver</argument> + <argument name="fieldTypeResolver" xsi:type="object">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver</argument> + </arguments> + </virtualType> + <virtualType name="elasticsearch5DynamicFieldProvider" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\DynamicField"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + <argument name="indexTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\Converter</argument> + </arguments> + </virtualType> + <type name="\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + </arguments> + </type> + <type name="\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + </arguments> + </type> + <virtualType name="elasticsearch5FieldTypeDateTimeResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + </arguments> + </virtualType> + <virtualType name="elasticsearch5FieldTypeFloatResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\FloatType"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + </arguments> + </virtualType> + <virtualType name="elasticsearch5FieldTypeDefaultResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver"> + <arguments> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + </arguments> + </virtualType> + <type name="\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\ProductFieldMapper"> + <arguments> + <argument name="fieldProvider" xsi:type="object">elasticsearch5FieldProvider</argument> + <argument name="fieldNameResolver" xsi:type="object">elasticsearch5FieldNameResolver</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\CategoryName"> + <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\ProductFieldMapper"> <arguments> - <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Position</argument> + <argument name="attributeAdapterProvider" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider</argument> + <argument name="fieldProvider" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface</argument> </arguments> </type> - <type name="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\Position"> + <type name="Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver"> <arguments> - <argument name="resolver" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldName\Resolver\DefaultResolver</argument> + <argument name="converter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\Converter</argument> + <argument name="fieldTypeConverter" xsi:type="object">Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter</argument> + <argument name="fieldTypeResolver" xsi:type="object">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver</argument> </arguments> </type> </config> From 704e082d9f9df714a606e82e41d3d58cd967ec2b Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Tue, 2 Oct 2018 18:04:49 +0300 Subject: [PATCH 275/812] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch - fix tests --- .../CategoryFieldsProvider.php | 1 - .../Adapter/DataMapper/ProductDataMapper.php | 2 +- .../FieldProvider/FieldIndex/Converter.php | 10 +++- .../FieldIndex/IndexResolver.php | 4 +- .../FieldProvider/FieldType/Converter.php | 10 +++- .../FieldType/Resolver/CompositeResolver.php | 9 +++- .../FieldType/Resolver/IntegerType.php | 5 +- .../FieldType/Resolver/KeywordType.php | 5 +- .../FieldMapper/ProductFieldMapper.php | 1 - .../CategoryFieldsProvider.php | 1 - .../Adapter/DataMapper/ProductDataMapper.php | 1 - .../FieldMapper/Product/AttributeAdapter.php | 12 ++--- .../AttributeAdapter/DummyAttribute.php | 49 ++++++++++++++++++- .../FieldMapper/Product/AttributeProvider.php | 32 +++++++++--- .../Product/CompositeFieldProvider.php | 10 +++- .../Product/FieldProvider/DynamicField.php | 48 ++++++++++++------ .../FieldProvider/FieldIndex/Converter.php | 11 ++++- .../FieldIndex/ConverterInterface.php | 2 +- .../FieldIndex/IndexResolver.php | 6 +-- .../FieldName/Resolver/CategoryName.php | 28 +++++++++-- .../FieldName/Resolver/CompositeResolver.php | 12 +++-- .../FieldName/Resolver/DefaultResolver.php | 16 +++++- .../FieldName/Resolver/NotEavAttribute.php | 6 ++- .../FieldName/Resolver/Position.php | 22 +++++++-- .../FieldName/Resolver/Price.php | 33 ++++++++++--- .../FieldName/Resolver/SpecialAttribute.php | 6 ++- .../FieldProvider/FieldType/Converter.php | 11 ++++- .../FieldType/Resolver/CompositeResolver.php | 9 +++- .../FieldType/Resolver/DateTimeType.php | 5 +- .../FieldType/Resolver/DefaultResolver.php | 5 +- .../FieldType/Resolver/FloatType.php | 5 +- .../FieldType/Resolver/IntegerType.php | 5 +- .../Product/FieldProvider/StaticField.php | 12 +++-- .../Elasticsearch/Model/Adapter/FieldType.php | 3 +- .../FieldIndex/IndexResolverTest.php | 9 ++-- .../FieldType/Resolver/IntegerTypeTest.php | 8 ++- .../FieldType/Resolver/KeywordTypeTest.php | 8 ++- .../Product/AttributeAdapterTest.php | 29 +++++++---- .../FieldProvider/DynamicFieldTest.php | 23 +++++---- .../FieldIndex/IndexResolverTest.php | 3 ++ .../FieldName/Resolver/CategoryNameTest.php | 8 ++- .../Resolver/DefaultResolverTest.php | 8 ++- .../Resolver/NotEavAttributeTest.php | 3 ++ .../FieldName/Resolver/PositionTest.php | 3 ++ .../FieldName/Resolver/PriceTest.php | 3 ++ .../Resolver/SpecialAttributeTest.php | 8 ++- .../FieldProvider/FieldType/ConverterTest.php | 20 ++------ .../FieldType/Resolver/DateTimeTypeTest.php | 8 ++- .../Resolver/DefaultResolverTest.php | 8 ++- .../FieldType/Resolver/FloatTypeTest.php | 3 ++ .../FieldType/Resolver/IntegerTypeTest.php | 8 ++- .../Product/FieldProvider/StaticFieldTest.php | 13 +++-- app/code/Magento/Elasticsearch/etc/di.xml | 1 + 53 files changed, 432 insertions(+), 139 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 7892e18b9ee4c..2ff37dab4fd2d 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -71,7 +71,6 @@ public function getFields(array $productIds, $storeId) * @param int $productId * @param array $categoryIndexData * @return array - * @throws \Magento\Framework\Exception\LocalizedException */ private function getProductCategoryData($productId, array $categoryIndexData) { diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php index de72485ddb84f..8c4022604afdf 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php @@ -390,7 +390,7 @@ protected function getProductPriceData($productId, $storeId, array $priceIndexDa foreach ($productPriceIndexData as $customerGroupId => $price) { $fieldName = $this->fieldMapper->getFieldName( 'price', - ['customerGroupId' => $customerGroupId] + ['customerGroupId' => $customerGroupId, 'websiteId' => $storeId] ); $result[$fieldName] = sprintf('%F', $price); } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php index b68d5e6f62d14..152c43d95e360 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -6,6 +6,7 @@ namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; +use Magento\Framework\Exception\LocalizedException; /** * Field type converter from internal index type to elastic service. @@ -27,10 +28,17 @@ class Converter implements ConverterInterface ]; /** - * {@inheritdoc} + * Get service field index type for elasticsearch 5. + * + * @param string $internalType + * @return string|boolean + * @throws LocalizedException */ public function convert(string $internalType) { + if (!isset($this->mapping[$internalType])) { + throw new LocalizedException(__('Unsupported internal field index type: %1', $internalType)); + } return $this->mapping[$internalType]; } } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php index 21429bc564374..7812018516151 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -15,8 +15,8 @@ as FieldTypeResolver; /** - * Field index resolver that provide index type for attribute in mapping. - * For example we need to set 'no'/false in case when attribute must be present in index data, + * Field index resolver that provides index type for the attribute in mapping. + * For example, we need to set ‘no’/false in the case when attribute must be present in index data, * but stay as not indexable. */ class IndexResolver implements ResolverInterface diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php index 9cb773adf914d..58215aec8e46e 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -6,6 +6,7 @@ namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; +use Magento\Framework\Exception\LocalizedException; /** * Field type converter from internal data types to elastic service. @@ -36,10 +37,17 @@ class Converter implements ConverterInterface ]; /** - * {@inheritdoc} + * Get service field type for elasticsearch 5. + * + * @param string $internalType + * @return string + * @throws LocalizedException */ public function convert(string $internalType): string { + if (!isset($this->mapping[$internalType])) { + throw new LocalizedException(__('Unsupported internal field type: %1', $internalType)); + } return $this->mapping[$internalType]; } } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index 719af357263d6..c1456dc55b0f1 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -24,11 +24,16 @@ class CompositeResolver implements ResolverInterface */ public function __construct(array $items) { - $this->items = $items; + $this->items = (function (ResolverInterface ...$items) { + return $items; + })(...$items); } /** - * {@inheritdoc} + * Get field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php index b777eb7e96ba5..d0ddd6115e557 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php @@ -36,7 +36,10 @@ public function __construct(ConverterInterface $fieldTypeConverter, $integerType } /** - * {@inheritdoc} + * Get integer field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php index 77ef77aaf8740..e27376f415610 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php @@ -29,7 +29,10 @@ public function __construct(ConverterInterface $fieldTypeConverter) } /** - * {@inheritdoc} + * Get field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php index e34e62a774925..463a7770357ad 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -107,7 +107,6 @@ public function __construct( * @param string $attributeCode * @param array $context * @return string - * @throws \Magento\Framework\Exception\LocalizedException */ public function getFieldName($attributeCode, $context = []) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 8feb8eb6088cc..fc557d427feea 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -71,7 +71,6 @@ public function getFields(array $productIds, $storeId) * @param int $productId * @param array $categoryIndexData * @return array - * @throws \Magento\Framework\Exception\LocalizedException */ private function getProductCategoryData($productId, array $categoryIndexData) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php index 1ca24a0c73025..f2082dd5fc243 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php @@ -14,5 +14,4 @@ */ class ProductDataMapper extends ElasticSearch5ProductDataMapper implements DataMapperInterface { - // } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php index 0661e86edceb7..6cfe4a256b11c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php @@ -6,7 +6,7 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; -use Magento\Framework\Model\AbstractExtensibleModel; +use Magento\Framework\Api\CustomAttributesDataInterface; /** * Product attribute adapter for elasticsearch context. @@ -14,7 +14,7 @@ class AttributeAdapter { /** - * @var AbstractExtensibleModel + * @var CustomAttributesDataInterface */ private $attribute; @@ -24,11 +24,11 @@ class AttributeAdapter private $attributeCode; /** - * @param AbstractExtensibleModel $attribute + * @param CustomAttributesDataInterface $attribute * @param string $attributeCode */ public function __construct( - AbstractExtensibleModel $attribute, + CustomAttributesDataInterface $attribute, string $attributeCode ) { $this->attribute = $attribute; @@ -168,9 +168,9 @@ public function getFrontendInput() /** * Get product attribute instance. * - * @return AbstractExtensibleModel|\Magento\Eav\Api\Data\AttributeInterface + * @return CustomAttributesDataInterface|\Magento\Eav\Api\Data\AttributeInterface */ - private function getAttribute(): AbstractExtensibleModel + private function getAttribute(): CustomAttributesDataInterface { return $this->attribute; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php index de824e4aeedb2..99fa1dc2c389c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php @@ -5,10 +5,55 @@ */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\Api\CustomAttributesDataInterface; + /** * Dummy class for Not EAV attribute. */ -class DummyAttribute extends \Magento\Framework\Model\AbstractExtensibleModel +class DummyAttribute implements CustomAttributesDataInterface { - // + /** + * Get an attribute value. + * + * @param string $attributeCode + * @return \Magento\Framework\Api\AttributeInterface|null + */ + public function getCustomAttribute($attributeCode) + { + return null; + } + + /** + * Set an attribute value for a given attribute code + * + * @param string $attributeCode + * @param mixed $attributeValue + * @return $this + */ + public function setCustomAttribute($attributeCode, $attributeValue) + { + return $this; + } + + /** + * Retrieve custom attributes values. + * + * @return \Magento\Framework\Api\AttributeInterface[]|null + */ + public function getCustomAttributes() + { + return null; + } + + /** + * Set array of custom attributes + * + * @param \Magento\Framework\Api\AttributeInterface[] $attributes + * @return $this + * @throws \LogicException + */ + public function setCustomAttributes(array $attributes) + { + return $this; + } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php index 8ae100f177494..1ab9d974aa75d 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php @@ -1,10 +1,15 @@ <?php - +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; use Magento\Eav\Model\Config; use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter\DummyAttribute; +use Magento\Framework\Exception\LocalizedException; +use Psr\Log\LoggerInterface; /** * Provide attribute adapter. @@ -16,14 +21,14 @@ class AttributeProvider * * @var \Magento\Framework\ObjectManagerInterface */ - private $objectManager = null; + private $objectManager; /** * Instance name to create * * @var string */ - private $instanceName = null; + private $instanceName; /** * @var Config @@ -35,21 +40,29 @@ class AttributeProvider */ private $cachedPool = []; + /** + * @var LoggerInterface + */ + private $logger; + /** * Factory constructor * * @param \Magento\Framework\ObjectManagerInterface $objectManager * @param Config $eavConfig + * @param LoggerInterface $logger * @param string $instanceName */ public function __construct( \Magento\Framework\ObjectManagerInterface $objectManager, Config $eavConfig, - $instanceName = 'Magento\\Elasticsearch\\Model\\Adapter\\FieldMapper\\Product\\AttributeAdapter' + LoggerInterface $logger, + $instanceName = AttributeAdapter::class ) { $this->objectManager = $objectManager; $this->instanceName = $instanceName; $this->eavConfig = $eavConfig; + $this->logger = $logger; } /** @@ -57,12 +70,19 @@ public function __construct( * * @param string $attributeCode * @return AttributeAdapter - * @throws \Magento\Framework\Exception\LocalizedException */ public function getByAttributeCode(string $attributeCode): AttributeAdapter { if (!isset($this->cachedPool[$attributeCode])) { - $attribute = $this->eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode); + $attribute = null; + try { + $attribute = $this->eavConfig->getAttribute( + ProductAttributeInterface::ENTITY_TYPE_CODE, + $attributeCode + ); + } catch (LocalizedException $exception) { + $this->logger->critical($exception); + } if (null === $attribute) { $attribute = $this->objectManager->create(DummyAttribute::class); } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php index 7d0d5fccbcf6c..3fc18ec925a48 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php @@ -1,4 +1,8 @@ <?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; @@ -13,11 +17,13 @@ class CompositeFieldProvider implements FieldProviderInterface private $providers; /** - * @param array $providers + * @param FieldProviderInterface[] $providers */ public function __construct(array $providers) { - $this->providers = $providers; + $this->providers = (function (FieldProviderInterface ...$providers) { + return $providers; + })(...$providers); } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php index a7773f0afda7e..757591e2dbba7 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php @@ -1,5 +1,8 @@ <?php - +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider; use Magento\Catalog\Api\CategoryListInterface; @@ -13,6 +16,8 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface as FieldNameResolver; use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Exception\LocalizedException; +use Psr\Log\LoggerInterface; /** * Provide dynamic fields for product. @@ -60,6 +65,11 @@ class DynamicField implements FieldProviderInterface */ private $fieldNameResolver; + /** + * @var LoggerInterface + */ + private $logger; + /** * @param FieldTypeConverterInterface $fieldTypeConverter * @param IndexTypeConverterInterface $indexTypeConverter @@ -68,6 +78,7 @@ class DynamicField implements FieldProviderInterface * @param CategoryListInterface $categoryList * @param FieldNameResolver $fieldNameResolver * @param AttributeProvider $attributeAdapterProvider + * @param LoggerInterface $logger */ public function __construct( FieldTypeConverterInterface $fieldTypeConverter, @@ -76,7 +87,8 @@ public function __construct( SearchCriteriaBuilder $searchCriteriaBuilder, CategoryListInterface $categoryList, FieldNameResolver $fieldNameResolver, - AttributeProvider $attributeAdapterProvider + AttributeProvider $attributeAdapterProvider, + LoggerInterface $logger ) { $this->groupRepository = $groupRepository; $this->searchCriteriaBuilder = $searchCriteriaBuilder; @@ -85,10 +97,14 @@ public function __construct( $this->categoryList = $categoryList; $this->fieldNameResolver = $fieldNameResolver; $this->attributeAdapterProvider = $attributeAdapterProvider; + $this->logger = $logger; } /** - * {@inheritdoc} + * Get mapping for dynamic fields. + * + * @param array $context + * @return array */ public function getFields(array $context = []): array { @@ -116,17 +132,21 @@ public function getFields(array $context = []): array ]; } - $groups = $this->groupRepository->getList($searchCriteria)->getItems(); - $priceAttribute = $this->attributeAdapterProvider->getByAttributeCode('price'); - foreach ($groups as $group) { - $groupPriceKey = $this->fieldNameResolver->getFieldName( - $priceAttribute, - ['customerGroupId' => $group->getId(), 'websiteId' => $context['websiteId']] - ); - $allAttributes[$groupPriceKey] = [ - 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_FLOAT), - 'store' => true - ]; + try { + $groups = $this->groupRepository->getList($searchCriteria)->getItems(); + $priceAttribute = $this->attributeAdapterProvider->getByAttributeCode('price'); + foreach ($groups as $group) { + $groupPriceKey = $this->fieldNameResolver->getFieldName( + $priceAttribute, + ['customerGroupId' => $group->getId(), 'websiteId' => $context['websiteId']] + ); + $allAttributes[$groupPriceKey] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_FLOAT), + 'store' => true + ]; + } + } catch (LocalizedException $exception) { + $this->logger->critical($exception); } return $allAttributes; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php index bd24fe6fa82a3..31da3fe79118c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -5,6 +5,8 @@ */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; +use Magento\Framework\Exception\LocalizedException; + /** * Field type converter from internal index type to elastic service. */ @@ -25,10 +27,17 @@ class Converter implements ConverterInterface ]; /** - * {@inheritdoc} + * Get service field index type for elasticsearch 2. + * + * @param string $internalType + * @return string|boolean + * @throws LocalizedException */ public function convert(string $internalType) { + if (!isset($this->mapping[$internalType])) { + throw new LocalizedException(__('Unsupported internal field index type: %1', $internalType)); + } return $this->mapping[$internalType]; } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php index 8199639fb8045..968f73e2b5d92 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php @@ -17,7 +17,7 @@ interface ConverterInterface public const INTERNAL_INDEX_VALUE = 'index'; /** - * Get service field type. + * Get service field index type. * * @param string $internalType * @return string|boolean diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php index 5a7203bf30bf6..c5fcf758da325 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -9,8 +9,8 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; /** - * Field index resolver that provide index type for attribute in mapping. - * For example we need to set 'no'/false in case when attribute must be present in index data, + * Field index resolver that provides index type for the attribute in mapping. + * For example, we need to set ‘no’/false in the case when attribute must be present in index data, * but stay as not indexable. */ class IndexResolver implements ResolverInterface @@ -34,7 +34,7 @@ public function __construct(ConverterInterface $converter) public function getFieldIndex(AttributeAdapter $attribute) { $index = null; - if (!$attribute->isSearchable() && !$attribute->isAlwaysIndexable()) { + if (!($attribute->isSearchable() || $attribute->isAlwaysIndexable())) { $index = $this->converter->convert(ConverterInterface::INTERNAL_NO_INDEX_VALUE); } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php index 1ad42a55cbbd4..d270cee431176 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php @@ -7,10 +7,12 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; use Magento\Framework\App\ObjectManager; +use Psr\Log\LoggerInterface; /** * Resolver field name for Category name attribute. @@ -28,13 +30,21 @@ class CategoryName implements ResolverInterface private $coreRegistry; /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param LoggerInterface $logger * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( + LoggerInterface $logger, StoreManager $storeManager = null, Registry $coreRegistry = null ) { + $this->logger = $logger; $this->storeManager = $storeManager ?: ObjectManager::getInstance() ->get(StoreManager::class); $this->coreRegistry = $coreRegistry ?: ObjectManager::getInstance() @@ -42,7 +52,11 @@ public function __construct( } /** - * {@inheritdoc} + * Get field name. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { @@ -58,16 +72,20 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin * * @param array $context * @return int - * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function resolveCategoryId($context): int { if (isset($context['categoryId'])) { $id = $context['categoryId']; } else { - $id = $this->coreRegistry->registry('current_category') - ? $this->coreRegistry->registry('current_category')->getId() - : $this->storeManager->getStore()->getRootCategoryId(); + $id = \Magento\Catalog\Model\Category::ROOT_CATEGORY_ID; + try { + $id = $this->coreRegistry->registry('current_category') + ? $this->coreRegistry->registry('current_category')->getId() + : $this->storeManager->getStore()->getRootCategoryId(); + } catch (LocalizedException $exception) { + $this->logger->critical($exception); + } } return $id; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php index 81ce3bf030806..0a7b2ae9538d7 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php @@ -20,15 +20,21 @@ class CompositeResolver implements ResolverInterface private $items; /** - * @param array $items + * @param ResolverInterface[] $items */ public function __construct(array $items) { - $this->items = $items; + $this->items = (function (ResolverInterface ...$items) { + return $items; + })(...$items); } /** - * {@inheritdoc} + * Get field name. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php index ab5486f3af292..b3f1a1d716557 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php @@ -42,7 +42,11 @@ public function __construct( } /** - * {@inheritdoc} + * Get field name. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { @@ -82,6 +86,8 @@ private function isStringServiceFieldType(string $serviceFieldType): bool } /** + * Get field name for query type fields. + * * @param string $frontendInput * @param string $fieldType * @param string $attributeCode @@ -98,6 +104,8 @@ private function getQueryTypeFieldName($frontendInput, $fieldType, $attributeCod } /** + * Prepare field name for complex fields. + * * @param string $frontendInput * @param string $fieldType * @param string $attributeCode @@ -105,9 +113,13 @@ private function getQueryTypeFieldName($frontendInput, $fieldType, $attributeCod */ private function getRefinedFieldName($frontendInput, $fieldType, $attributeCode) { + $stringTypeKey = $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_STRING); switch ($frontendInput) { case 'select': - return in_array($fieldType, ['text', 'integer'], true) ? $attributeCode . '_value' : $attributeCode; + case 'multiselect': + return in_array($fieldType, [$stringTypeKey, 'integer'], true) + ? $attributeCode . '_value' + : $attributeCode; case 'boolean': return $fieldType === 'integer' ? $attributeCode . '_value' : $attributeCode; default: diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php index 094148aa3e632..d92730595abfd 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php @@ -15,7 +15,11 @@ class NotEavAttribute implements ResolverInterface { /** - * {@inheritdoc} + * Get field name for not EAV attributes. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php index beb1a675e89da..2e7ea841949f4 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php @@ -7,10 +7,12 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; use Magento\Framework\App\ObjectManager; +use Psr\Log\LoggerInterface; /** * Resolver field name for position attribute. @@ -28,13 +30,21 @@ class Position implements ResolverInterface private $coreRegistry; /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param LoggerInterface $logger * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( + LoggerInterface $logger, StoreManager $storeManager = null, Registry $coreRegistry = null ) { + $this->logger = $logger; $this->storeManager = $storeManager ?: ObjectManager::getInstance() ->get(StoreManager::class); $this->coreRegistry = $coreRegistry ?: ObjectManager::getInstance() @@ -58,16 +68,20 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin * * @param array $context * @return int - * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function resolveCategoryId($context) { if (isset($context['categoryId'])) { $id = $context['categoryId']; } else { - $id = $this->coreRegistry->registry('current_category') - ? $this->coreRegistry->registry('current_category')->getId() - : $this->storeManager->getStore()->getRootCategoryId(); + $id = \Magento\Catalog\Model\Category::ROOT_CATEGORY_ID; + try { + $id = $this->coreRegistry->registry('current_category') + ? $this->coreRegistry->registry('current_category')->getId() + : $this->storeManager->getStore()->getRootCategoryId(); + } catch (LocalizedException $exception) { + $this->logger->critical($exception); + } } return $id; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php index 4449ec57523b9..89d43d7f5919f 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php @@ -7,9 +7,11 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; use Magento\Customer\Model\Session as CustomerSession; +use Magento\Framework\Exception\LocalizedException; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; +use Psr\Log\LoggerInterface; /** * Resolver field name for price attribute. @@ -27,17 +29,31 @@ class Price implements ResolverInterface private $storeManager; /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param LoggerInterface $logger * @param CustomerSession $customerSession * @param StoreManager $storeManager */ - public function __construct(CustomerSession $customerSession, StoreManager $storeManager) - { + public function __construct( + LoggerInterface $logger, + CustomerSession $customerSession = null, + StoreManager $storeManager = null + ) { $this->customerSession = $customerSession; $this->storeManager = $storeManager; + $this->logger = $logger; } /** - * {@inheritdoc} + * Get field name for price type attributes. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { @@ -45,9 +61,14 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin $customerGroupId = !empty($context['customerGroupId']) ? $context['customerGroupId'] : $this->customerSession->getCustomerGroupId(); - $websiteId = !empty($context['websiteId']) - ? $context['websiteId'] - : $this->storeManager->getStore()->getWebsiteId(); + $websiteId = \Magento\Store\Model\Store::DEFAULT_STORE_ID; + try { + $websiteId = !empty($context['websiteId']) + ? $context['websiteId'] + : $this->storeManager->getStore()->getWebsiteId(); + } catch (LocalizedException $exception) { + $this->logger->critical($exception); + } return 'price_' . $customerGroupId . '_' . $websiteId; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php index 14906fa5cee82..813c6c71c9d1a 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php @@ -15,7 +15,11 @@ class SpecialAttribute implements ResolverInterface { /** - * {@inheritdoc} + * Get field name for special list of attributes. + * + * @param AttributeAdapter $attribute + * @param array $context + * @return string */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php index be8ef76e666fe..0c5f5299344fe 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -5,6 +5,8 @@ */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; +use Magento\Framework\Exception\LocalizedException; + /** * Field type converter from internal data types to elastic service. */ @@ -33,10 +35,17 @@ class Converter implements ConverterInterface ]; /** - * {@inheritdoc} + * Get service field type for elasticsearch 2. + * + * @param string $internalType + * @return string + * @throws LocalizedException */ public function convert(string $internalType): string { + if (!isset($this->mapping[$internalType])) { + throw new LocalizedException(__('Unsupported internal field type: %1', $internalType)); + } return $this->mapping[$internalType]; } } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index 7a4c06c56d095..6e541f1060898 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -24,11 +24,16 @@ class CompositeResolver implements ResolverInterface */ public function __construct(array $items) { - $this->items = $items; + $this->items = (function (ResolverInterface ...$items) { + return $items; + })(...$items); } /** - * {@inheritdoc} + * Get field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php index ff029ff8610f5..3430288f59405 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php @@ -29,7 +29,10 @@ public function __construct(ConverterInterface $fieldTypeConverter) } /** - * {@inheritdoc} + * Get datetime field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php index 8e754cddd3e92..894834f30b47c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php @@ -29,7 +29,10 @@ public function __construct(ConverterInterface $fieldTypeConverter) } /** - * {@inheritdoc} + * Get default field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php index 9fe03d4cbab49..e45989b54b921 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php @@ -29,7 +29,10 @@ public function __construct(ConverterInterface $fieldTypeConverter) } /** - * {@inheritdoc} + * Get float field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php index c4280505f1190..3fa24b3b2af56 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php @@ -29,7 +29,10 @@ public function __construct(ConverterInterface $fieldTypeConverter) } /** - * {@inheritdoc} + * Get integer field type. + * + * @param AttributeAdapter $attribute + * @return string */ public function getFieldType(AttributeAdapter $attribute): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php index 89748d6428e4d..d15040f24d775 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php @@ -1,5 +1,8 @@ <?php - +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider; use Magento\Eav\Model\Config; @@ -16,7 +19,7 @@ as FieldIndexResolver; /** - * Provide static fields for product. + * Provide static fields for mapping of product. */ class StaticField implements FieldProviderInterface { @@ -75,7 +78,10 @@ public function __construct( } /** - * {@inheritdoc} + * Get static fields. + * + * @param array $context + * @return array */ public function getFields(array $context = []): array { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php index be6462156c471..7ad6539e6b718 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php @@ -14,7 +14,7 @@ * @api * @since 100.1.0 * - * @deprecated This class provide not full data about field type. Only basic rules apply on this class. + * @deprecated This class provide not full data about field type. Only basic rules apply in this class. * @see ResolverInterface */ class FieldType @@ -35,6 +35,7 @@ class FieldType /**#@-*/ /** + * * @deprecated * @see ResolverInterface::getFieldType * diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php index a4503924c8455..9b0159332d691 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php @@ -13,11 +13,15 @@ as FieldTypeConverterInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface as FieldTypeResolver; +use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver; +/** + * @SuppressWarnings(PHPMD) + */ class IndexResolverTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver + * @var IndexResolver */ private $resolver; @@ -58,7 +62,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver::class, + IndexResolver::class, [ 'converter' => $this->converter, 'fieldTypeConverter' => $this->fieldTypeConverter, @@ -71,7 +75,6 @@ protected function setUp() * @dataProvider getFieldIndexProvider * @param $isSearchable * @param $isAlwaysIndexable - * @param $stringServiceFieldType * @param $isComplexType * @param $isIntegerType * @param $isBooleanType diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php index d4536e4a53b62..5f419dea1f26a 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -10,11 +10,15 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType; +/** + * @SuppressWarnings(PHPMD) + */ class IntegerTypeTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType + * @var IntegerType */ private $resolver; @@ -38,7 +42,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType::class, + IntegerType::class, [ 'fieldTypeConverter' => $this->fieldTypeConverter, ] diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php index cd0b88e6ce51d..be8b2e30e5f4b 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php @@ -9,11 +9,15 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType; +/** + * @SuppressWarnings(PHPMD) + */ class KeywordTypeTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType + * @var KeywordType */ private $resolver; @@ -37,7 +41,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType::class, + KeywordType::class, [ 'fieldTypeConverter' => $this->fieldTypeConverter, ] diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php index ccefb2c4844a7..39543150dd849 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php @@ -6,11 +6,15 @@ namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product; +use Magento\Framework\Api\CustomAttributesDataInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use Magento\Framework\Model\AbstractExtensibleModel; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; +/** + * @SuppressWarnings(PHPMD) + */ class AttributeAdapterTest extends \PHPUnit\Framework\TestCase { /** @@ -30,7 +34,7 @@ class AttributeAdapterTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - $this->attribute = $this->getMockBuilder(AbstractExtensibleModel::class) + $this->attribute = $this->getMockBuilder(CustomAttributesDataInterface::class) ->disableOriginalConstructor() ->setMethods([ 'getIsFilterable', @@ -41,7 +45,7 @@ protected function setUp() 'getFrontendInput', 'usesSource', ]) - ->getMock(); + ->getMockForAbstractClass(); $objectManager = new ObjectManagerHelper($this); @@ -114,7 +118,8 @@ public function testIsSearchable( * @param $expected * @return void */ - public function testIsAlwaysIndexable($expected) { + public function testIsAlwaysIndexable($expected) + { $this->assertEquals( $expected, $this->adapter->isAlwaysIndexable() @@ -127,7 +132,8 @@ public function testIsAlwaysIndexable($expected) { * @param $expected * @return void */ - public function testIsDateTimeType($backendType, $expected) { + public function testIsDateTimeType($backendType, $expected) + { $this->attribute ->method('getBackendType') ->willReturn($backendType); @@ -143,7 +149,8 @@ public function testIsDateTimeType($backendType, $expected) { * @param $expected * @return void */ - public function testIsFloatType($backendType, $expected) { + public function testIsFloatType($backendType, $expected) + { $this->attribute ->method('getBackendType') ->willReturn($backendType); @@ -159,7 +166,8 @@ public function testIsFloatType($backendType, $expected) { * @param $expected * @return void */ - public function testIsIntegerType($backendType, $expected) { + public function testIsIntegerType($backendType, $expected) + { $this->attribute ->method('getBackendType') ->willReturn($backendType); @@ -176,7 +184,8 @@ public function testIsIntegerType($backendType, $expected) { * @param $expected * @return void */ - public function testIsBooleanType($frontendInput, $backendType, $expected) { + public function testIsBooleanType($frontendInput, $backendType, $expected) + { $this->attribute ->method('getBackendType') ->willReturn($backendType); @@ -196,7 +205,8 @@ public function testIsBooleanType($frontendInput, $backendType, $expected) { * @param $expected * @return void */ - public function testIsComplexType($frontendInput, $usesSource, $expected) { + public function testIsComplexType($frontendInput, $usesSource, $expected) + { $this->attribute ->method('usesSource') ->willReturn($usesSource); @@ -214,7 +224,8 @@ public function testIsComplexType($frontendInput, $usesSource, $expected) { * @param $expected * @return void */ - public function testIsEavAttribute($expected) { + public function testIsEavAttribute($expected) + { $this->assertEquals( $expected, $this->adapter->isEavAttribute() diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php index 4907c89d35aaa..b62fab78e6a0e 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php @@ -24,6 +24,9 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface as FieldNameResolver; +/** + * @SuppressWarnings(PHPMD) + */ class DynamicFieldTest extends \PHPUnit\Framework\TestCase { /** @@ -184,8 +187,8 @@ public function testGetAllAttributesTypes( $this->fieldNameResolver->expects($this->any()) ->method('getFieldName') ->will($this->returnCallback( - function($attribute)use ($categoryId) { - static $callCount = array(); + function ($attribute) use ($categoryId) { + static $callCount = []; $attributeCode = $attribute->getAttributeCode(); $callCount[$attributeCode] = !isset($callCount[$attributeCode]) ? 1 : ++$callCount[$attributeCode]; @@ -215,12 +218,12 @@ function($attribute)use ($categoryId) { ->method('getByAttributeCode') ->with($this->anything()) ->will($this->returnCallback( - function($code) use( + function ($code) use ( $categoryAttributeMock, $positionAttributeMock, $priceAttributeMock ) { - static $callCount = array(); + static $callCount = []; $callCount[$code] = !isset($callCount[$code]) ? 1 : ++$callCount[$code]; if ($code === 'position') { @@ -236,15 +239,16 @@ function($code) use( ->method('convert') ->with($this->anything()) ->will($this->returnCallback( - function($type) use ($complexType) { - static $callCount = array(); + function ($type) use ($complexType) { + static $callCount = []; $callCount[$type] = !isset($callCount[$type]) ? 1 : ++$callCount[$type]; if ($type === 'string') { return 'string'; - } if ($type === 'string') { + } + if ($type === 'string') { return 'string'; - } elseif($type === 'float') { + } elseif ($type === 'float') { return 'float'; } else { return $complexType; @@ -252,10 +256,9 @@ function($type) use ($complexType) { } )); - $this->assertEquals( $expected, - $this->provider->getFields(['storeId' => 1]) + $this->provider->getFields(['websiteId' => 1]) ); } diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php index 497f3d957e181..96cebfe408db5 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php @@ -10,6 +10,9 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +/** + * @SuppressWarnings(PHPMD) + */ class IndexResolverTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php index 9944874b97a92..1cdeb0ac867b4 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php @@ -12,11 +12,15 @@ use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Store\Api\Data\StoreInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName; +/** + * @SuppressWarnings(PHPMD) + */ class CategoryNameTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName + * @var CategoryName */ private $resolver; @@ -49,7 +53,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName::class, + CategoryName::class, [ 'storeManager' => $this->storeManager, 'coreRegistry' => $this->coreRegistry, diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php index 2fe75d46eb36b..3d2ecadd28463 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php @@ -12,11 +12,15 @@ as FieldTypeResolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver; +/** + * @SuppressWarnings(PHPMD) + */ class DefaultResolverTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver + * @var DefaultResolver */ private $resolver; @@ -48,7 +52,7 @@ protected function setUp() ->getMockForAbstractClass(); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver::class, + DefaultResolver::class, [ 'fieldTypeResolver' => $this->fieldTypeResolver, 'fieldTypeConverter' => $this->fieldTypeConverter diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php index c76bb8661d761..3178c430835e1 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php @@ -13,6 +13,9 @@ use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Store\Api\Data\StoreInterface; +/** + * @SuppressWarnings(PHPMD) + */ class NotEavAttributeTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php index d1d6bb5a91c22..104db78d3c08f 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php @@ -13,6 +13,9 @@ use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Store\Api\Data\StoreInterface; +/** + * @SuppressWarnings(PHPMD) + */ class PositionTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php index 649244fd2a33c..584b7bf95f41c 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php @@ -12,6 +12,9 @@ use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Store\Api\Data\StoreInterface; +/** + * @SuppressWarnings(PHPMD) + */ class PriceTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php index 849bf0e35bf48..6efd7acee665a 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php @@ -8,11 +8,15 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute; +/** + * @SuppressWarnings(PHPMD) + */ class SpecialAttributeTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute + * @var SpecialAttribute */ private $resolver; @@ -26,7 +30,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute::class + SpecialAttribute::class ); } diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php index eec577988d046..1a0fb93441ae7 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php @@ -4,11 +4,13 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\FieldProvider\Product\FieldType; +namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; -use Psr\Log\LoggerInterface; +/** + * @SuppressWarnings(PHPMD) + */ class ConverterTest extends \PHPUnit\Framework\TestCase { /** @@ -16,11 +18,6 @@ class ConverterTest extends \PHPUnit\Framework\TestCase */ private $converter; - /** - * @var LoggerInterface - */ - private $logger; - /** * Set up test environment * @@ -28,17 +25,10 @@ class ConverterTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - $this->logger = $this->getMockBuilder(LoggerInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - $objectManager = new ObjectManagerHelper($this); $this->converter = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter::class, - [ - 'logger' => $this->logger, - ] + \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter::class ); } diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php index 43eff23702aa7..34c36bd456dfe 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php @@ -10,11 +10,15 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType; +/** + * @SuppressWarnings(PHPMD) + */ class DateTimeTypeTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType + * @var DateTimeType */ private $resolver; @@ -38,7 +42,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType::class, + DateTimeType::class, [ 'fieldTypeConverter' => $this->fieldTypeConverter, ] diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php index 983a1b941a2c3..e086a959bdde7 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php @@ -10,11 +10,15 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver; +/** + * @SuppressWarnings(PHPMD) + */ class DefaultResolverTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver + * @var DefaultResolver */ private $resolver; @@ -38,7 +42,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver::class, + DefaultResolver::class, [ 'fieldTypeConverter' => $this->fieldTypeConverter, ] diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php index 757d830bb49b3..435883c847b3c 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php @@ -11,6 +11,9 @@ as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +/** + * @SuppressWarnings(PHPMD) + */ class FloatTypeTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php index bd88b4bcc8a1b..bb111f5f5f97a 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -10,11 +10,15 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType; +/** + * @SuppressWarnings(PHPMD) + */ class IntegerTypeTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType + * @var IntegerType */ private $resolver; @@ -38,7 +42,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType::class, + IntegerType::class, [ 'fieldTypeConverter' => $this->fieldTypeConverter, ] diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php index 1efc31ac0942f..0937bc570a1d5 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php @@ -20,6 +20,9 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ResolverInterface as FieldIndexResolver; +/** + * @SuppressWarnings(PHPMD) + */ class StaticFieldTest extends \PHPUnit\Framework\TestCase { /** @@ -158,15 +161,16 @@ public function testGetAllAttributesTypes( ->method('convert') ->with($this->anything()) ->will($this->returnCallback( - function($type) use ($complexType) { - static $callCount = array(); + function ($type) use ($complexType) { + static $callCount = []; $callCount[$type] = !isset($callCount[$type]) ? 1 : ++$callCount[$type]; if ($type === 'string') { return 'string'; - } if ($type === 'string') { + } + if ($type === 'string') { return 'string'; - } elseif($type === 'float') { + } elseif ($type === 'float') { return 'float'; } else { return $complexType; @@ -174,7 +178,6 @@ function($type) use ($complexType) { } )); - $this->assertEquals( $expected, $this->provider->getFields(['storeId' => 1]) diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index 8e39e048cfba6..db2d95553d4fc 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -403,6 +403,7 @@ <arguments> <argument name="attributeAdapterProvider" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider</argument> <argument name="fieldProvider" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface</argument> + <argument name="fieldNameResolver" xsi:type="object">Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface</argument> </arguments> </type> <type name="Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\IndexResolver"> From d484aae7e66390f921c90e4bce1ce7cfc5b63db2 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Wed, 3 Oct 2018 14:05:44 +0300 Subject: [PATCH 276/812] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch - fix tests --- .../FieldProvider/FieldIndex/Converter.php | 5 +-- .../FieldProvider/FieldType/Converter.php | 5 +-- .../FieldType/Resolver/CompositeResolver.php | 11 +++-- .../FieldMapper/Product/AttributeProvider.php | 19 +++----- .../Product/CompositeFieldProvider.php | 11 +++-- .../Product/FieldProvider/DynamicField.php | 43 ++++++------------- .../FieldProvider/FieldIndex/Converter.php | 6 +-- .../FieldName/Resolver/CategoryName.php | 26 ++--------- .../FieldName/Resolver/CompositeResolver.php | 11 +++-- .../FieldName/Resolver/Position.php | 26 ++--------- .../FieldName/Resolver/Price.php | 34 ++++----------- .../FieldProvider/FieldType/Converter.php | 6 +-- .../FieldType/Resolver/CompositeResolver.php | 11 +++-- 13 files changed, 75 insertions(+), 139 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php index 152c43d95e360..a5969f58c27f9 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -6,7 +6,6 @@ namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; -use Magento\Framework\Exception\LocalizedException; /** * Field type converter from internal index type to elastic service. @@ -32,12 +31,12 @@ class Converter implements ConverterInterface * * @param string $internalType * @return string|boolean - * @throws LocalizedException + * @throws \DomainException */ public function convert(string $internalType) { if (!isset($this->mapping[$internalType])) { - throw new LocalizedException(__('Unsupported internal field index type: %1', $internalType)); + throw new \DomainException(sprintf('Unsupported internal field index type: %s', $internalType)); } return $this->mapping[$internalType]; } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php index 58215aec8e46e..ae9db7c5c348e 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -6,7 +6,6 @@ namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; -use Magento\Framework\Exception\LocalizedException; /** * Field type converter from internal data types to elastic service. @@ -41,12 +40,12 @@ class Converter implements ConverterInterface * * @param string $internalType * @return string - * @throws LocalizedException + * @throws \DomainException */ public function convert(string $internalType): string { if (!isset($this->mapping[$internalType])) { - throw new LocalizedException(__('Unsupported internal field type: %1', $internalType)); + throw new \DomainException(sprintf('Unsupported internal field type: %s', $internalType)); } return $this->mapping[$internalType]; } diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index c1456dc55b0f1..b098d2aab79bf 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -24,9 +24,14 @@ class CompositeResolver implements ResolverInterface */ public function __construct(array $items) { - $this->items = (function (ResolverInterface ...$items) { - return $items; - })(...$items); + foreach ($items as $item) { + if (!$item instanceof ResolverInterface) { + throw new \InvalidArgumentException( + sprintf('Instance of the field type resolver is expected, got %s instead.', get_class($item)) + ); + } + } + $this->items = $items; } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php index 1ab9d974aa75d..bf8afb5e37530 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php @@ -8,7 +8,6 @@ use Magento\Eav\Model\Config; use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter\DummyAttribute; -use Magento\Framework\Exception\LocalizedException; use Psr\Log\LoggerInterface; /** @@ -66,23 +65,15 @@ public function __construct( } /** - * Create class instance with specified parameters - * - * @param string $attributeCode - * @return AttributeAdapter + * {@inheritdoc} */ public function getByAttributeCode(string $attributeCode): AttributeAdapter { if (!isset($this->cachedPool[$attributeCode])) { - $attribute = null; - try { - $attribute = $this->eavConfig->getAttribute( - ProductAttributeInterface::ENTITY_TYPE_CODE, - $attributeCode - ); - } catch (LocalizedException $exception) { - $this->logger->critical($exception); - } + $attribute = $this->eavConfig->getAttribute( + ProductAttributeInterface::ENTITY_TYPE_CODE, + $attributeCode + ); if (null === $attribute) { $attribute = $this->objectManager->create(DummyAttribute::class); } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php index 3fc18ec925a48..f1622a900c7b3 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php @@ -21,9 +21,14 @@ class CompositeFieldProvider implements FieldProviderInterface */ public function __construct(array $providers) { - $this->providers = (function (FieldProviderInterface ...$providers) { - return $providers; - })(...$providers); + foreach ($providers as $provider) { + if (!$provider instanceof FieldProviderInterface) { + throw new \InvalidArgumentException( + sprintf('Instance of the field provider is expected, got %s instead.', get_class($provider)) + ); + } + } + $this->providers = $providers; } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php index 757591e2dbba7..877b81f367f4c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php @@ -16,8 +16,6 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface as FieldNameResolver; use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Framework\Exception\LocalizedException; -use Psr\Log\LoggerInterface; /** * Provide dynamic fields for product. @@ -65,11 +63,6 @@ class DynamicField implements FieldProviderInterface */ private $fieldNameResolver; - /** - * @var LoggerInterface - */ - private $logger; - /** * @param FieldTypeConverterInterface $fieldTypeConverter * @param IndexTypeConverterInterface $indexTypeConverter @@ -78,7 +71,6 @@ class DynamicField implements FieldProviderInterface * @param CategoryListInterface $categoryList * @param FieldNameResolver $fieldNameResolver * @param AttributeProvider $attributeAdapterProvider - * @param LoggerInterface $logger */ public function __construct( FieldTypeConverterInterface $fieldTypeConverter, @@ -87,8 +79,7 @@ public function __construct( SearchCriteriaBuilder $searchCriteriaBuilder, CategoryListInterface $categoryList, FieldNameResolver $fieldNameResolver, - AttributeProvider $attributeAdapterProvider, - LoggerInterface $logger + AttributeProvider $attributeAdapterProvider ) { $this->groupRepository = $groupRepository; $this->searchCriteriaBuilder = $searchCriteriaBuilder; @@ -97,14 +88,10 @@ public function __construct( $this->categoryList = $categoryList; $this->fieldNameResolver = $fieldNameResolver; $this->attributeAdapterProvider = $attributeAdapterProvider; - $this->logger = $logger; } /** - * Get mapping for dynamic fields. - * - * @param array $context - * @return array + * {@inheritdoc} */ public function getFields(array $context = []): array { @@ -132,21 +119,17 @@ public function getFields(array $context = []): array ]; } - try { - $groups = $this->groupRepository->getList($searchCriteria)->getItems(); - $priceAttribute = $this->attributeAdapterProvider->getByAttributeCode('price'); - foreach ($groups as $group) { - $groupPriceKey = $this->fieldNameResolver->getFieldName( - $priceAttribute, - ['customerGroupId' => $group->getId(), 'websiteId' => $context['websiteId']] - ); - $allAttributes[$groupPriceKey] = [ - 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_FLOAT), - 'store' => true - ]; - } - } catch (LocalizedException $exception) { - $this->logger->critical($exception); + $groups = $this->groupRepository->getList($searchCriteria)->getItems(); + $priceAttribute = $this->attributeAdapterProvider->getByAttributeCode('price'); + foreach ($groups as $group) { + $groupPriceKey = $this->fieldNameResolver->getFieldName( + $priceAttribute, + ['customerGroupId' => $group->getId(), 'websiteId' => $context['websiteId']] + ); + $allAttributes[$groupPriceKey] = [ + 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_FLOAT), + 'store' => true + ]; } return $allAttributes; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php index 31da3fe79118c..bbe72821671dc 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -5,8 +5,6 @@ */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; -use Magento\Framework\Exception\LocalizedException; - /** * Field type converter from internal index type to elastic service. */ @@ -31,12 +29,12 @@ class Converter implements ConverterInterface * * @param string $internalType * @return string|boolean - * @throws LocalizedException + * @throws \DomainException */ public function convert(string $internalType) { if (!isset($this->mapping[$internalType])) { - throw new LocalizedException(__('Unsupported internal field index type: %1', $internalType)); + throw new \DomainException(sprintf('Unsupported internal field index type: %s', $internalType)); } return $this->mapping[$internalType]; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php index d270cee431176..d5e2b09f4ea2c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php @@ -7,12 +7,10 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; -use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; use Magento\Framework\App\ObjectManager; -use Psr\Log\LoggerInterface; /** * Resolver field name for Category name attribute. @@ -30,21 +28,13 @@ class CategoryName implements ResolverInterface private $coreRegistry; /** - * @var LoggerInterface - */ - private $logger; - - /** - * @param LoggerInterface $logger * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( - LoggerInterface $logger, StoreManager $storeManager = null, Registry $coreRegistry = null ) { - $this->logger = $logger; $this->storeManager = $storeManager ?: ObjectManager::getInstance() ->get(StoreManager::class); $this->coreRegistry = $coreRegistry ?: ObjectManager::getInstance() @@ -68,24 +58,16 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin } /** - * Resolve category id. - * - * @param array $context - * @return int + * {@inheritdoc} */ private function resolveCategoryId($context): int { if (isset($context['categoryId'])) { $id = $context['categoryId']; } else { - $id = \Magento\Catalog\Model\Category::ROOT_CATEGORY_ID; - try { - $id = $this->coreRegistry->registry('current_category') - ? $this->coreRegistry->registry('current_category')->getId() - : $this->storeManager->getStore()->getRootCategoryId(); - } catch (LocalizedException $exception) { - $this->logger->critical($exception); - } + $id = $this->coreRegistry->registry('current_category') + ? $this->coreRegistry->registry('current_category')->getId() + : $this->storeManager->getStore()->getRootCategoryId(); } return $id; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php index 0a7b2ae9538d7..5f48cc8b1a529 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php @@ -24,9 +24,14 @@ class CompositeResolver implements ResolverInterface */ public function __construct(array $items) { - $this->items = (function (ResolverInterface ...$items) { - return $items; - })(...$items); + foreach ($items as $item) { + if (!$item instanceof ResolverInterface) { + throw new \InvalidArgumentException( + sprintf('Instance of the field name resolver is expected, got %s instead.', get_class($item)) + ); + } + } + $this->items = $items; } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php index 2e7ea841949f4..99c7f82be117e 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php @@ -7,12 +7,10 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; -use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Registry; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; use Magento\Framework\App\ObjectManager; -use Psr\Log\LoggerInterface; /** * Resolver field name for position attribute. @@ -30,21 +28,13 @@ class Position implements ResolverInterface private $coreRegistry; /** - * @var LoggerInterface - */ - private $logger; - - /** - * @param LoggerInterface $logger * @param StoreManager $storeManager * @param Registry $coreRegistry */ public function __construct( - LoggerInterface $logger, StoreManager $storeManager = null, Registry $coreRegistry = null ) { - $this->logger = $logger; $this->storeManager = $storeManager ?: ObjectManager::getInstance() ->get(StoreManager::class); $this->coreRegistry = $coreRegistry ?: ObjectManager::getInstance() @@ -64,24 +54,16 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin } /** - * Resolve category id. - * - * @param array $context - * @return int + * {@inheritdoc} */ private function resolveCategoryId($context) { if (isset($context['categoryId'])) { $id = $context['categoryId']; } else { - $id = \Magento\Catalog\Model\Category::ROOT_CATEGORY_ID; - try { - $id = $this->coreRegistry->registry('current_category') - ? $this->coreRegistry->registry('current_category')->getId() - : $this->storeManager->getStore()->getRootCategoryId(); - } catch (LocalizedException $exception) { - $this->logger->critical($exception); - } + $id = $this->coreRegistry->registry('current_category') + ? $this->coreRegistry->registry('current_category')->getId() + : $this->storeManager->getStore()->getRootCategoryId(); } return $id; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php index 89d43d7f5919f..a7a4d506859c9 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php @@ -6,12 +6,11 @@ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; +use Magento\Framework\App\ObjectManager; use Magento\Customer\Model\Session as CustomerSession; -use Magento\Framework\Exception\LocalizedException; use Magento\Store\Model\StoreManagerInterface as StoreManager; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; -use Psr\Log\LoggerInterface; /** * Resolver field name for price attribute. @@ -29,31 +28,21 @@ class Price implements ResolverInterface private $storeManager; /** - * @var LoggerInterface - */ - private $logger; - - /** - * @param LoggerInterface $logger * @param CustomerSession $customerSession * @param StoreManager $storeManager */ public function __construct( - LoggerInterface $logger, CustomerSession $customerSession = null, StoreManager $storeManager = null ) { - $this->customerSession = $customerSession; - $this->storeManager = $storeManager; - $this->logger = $logger; + $this->storeManager = $storeManager ?: ObjectManager::getInstance() + ->get(StoreManager::class); + $this->customerSession = $customerSession ?: ObjectManager::getInstance() + ->get(CustomerSession::class); } /** - * Get field name for price type attributes. - * - * @param AttributeAdapter $attribute - * @param array $context - * @return string + * {@inheritdoc} */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { @@ -61,14 +50,9 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin $customerGroupId = !empty($context['customerGroupId']) ? $context['customerGroupId'] : $this->customerSession->getCustomerGroupId(); - $websiteId = \Magento\Store\Model\Store::DEFAULT_STORE_ID; - try { - $websiteId = !empty($context['websiteId']) - ? $context['websiteId'] - : $this->storeManager->getStore()->getWebsiteId(); - } catch (LocalizedException $exception) { - $this->logger->critical($exception); - } + $websiteId = !empty($context['websiteId']) + ? $context['websiteId'] + : $this->storeManager->getStore()->getWebsiteId(); return 'price_' . $customerGroupId . '_' . $websiteId; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php index 0c5f5299344fe..147abc893eba3 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -5,8 +5,6 @@ */ namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; -use Magento\Framework\Exception\LocalizedException; - /** * Field type converter from internal data types to elastic service. */ @@ -39,12 +37,12 @@ class Converter implements ConverterInterface * * @param string $internalType * @return string - * @throws LocalizedException + * @throws \DomainException */ public function convert(string $internalType): string { if (!isset($this->mapping[$internalType])) { - throw new LocalizedException(__('Unsupported internal field type: %1', $internalType)); + throw new \DomainException(sprintf('Unsupported internal field type: %s', $internalType)); } return $this->mapping[$internalType]; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index 6e541f1060898..e2a0025625b93 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -24,9 +24,14 @@ class CompositeResolver implements ResolverInterface */ public function __construct(array $items) { - $this->items = (function (ResolverInterface ...$items) { - return $items; - })(...$items); + foreach ($items as $item) { + if (!$item instanceof ResolverInterface) { + throw new \InvalidArgumentException( + sprintf('Instance of the field type resolver is expected, got %s instead.', get_class($item)) + ); + } + } + $this->items = $items; } /** From cf0c2dc6f16a01a09c5eb7cb68cf3105b1ed6d5b Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Wed, 3 Oct 2018 18:43:06 +0300 Subject: [PATCH 277/812] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch - fix tests --- .../FieldType/Resolver/CompositeResolver.php | 4 ++-- .../Product/AttributeAdapter/DummyAttribute.php | 1 + .../FieldName/Resolver/NotEavAttributeTest.php | 9 +++------ 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index b098d2aab79bf..bcc6a430e6fa3 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -28,8 +28,8 @@ public function __construct(array $items) if (!$item instanceof ResolverInterface) { throw new \InvalidArgumentException( sprintf('Instance of the field type resolver is expected, got %s instead.', get_class($item)) - ); - } + ); + } } $this->items = $items; } diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php index 99fa1dc2c389c..85e8722627c2b 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php @@ -9,6 +9,7 @@ /** * Dummy class for Not EAV attribute. + * @SuppressWarnings(PHPMD) */ class DummyAttribute implements CustomAttributesDataInterface { diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php index 3178c430835e1..fbf7479d9aa1f 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php @@ -6,12 +6,9 @@ namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; -use Magento\Catalog\Api\Data\CategoryInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; -use Magento\Framework\Registry; -use Magento\Store\Model\StoreManagerInterface as StoreManager; -use Magento\Store\Api\Data\StoreInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute; /** * @SuppressWarnings(PHPMD) @@ -19,7 +16,7 @@ class NotEavAttributeTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute + * @var NotEavAttribute */ private $resolver; @@ -33,7 +30,7 @@ protected function setUp() $objectManager = new ObjectManagerHelper($this); $this->resolver = $objectManager->getObject( - \Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute::class + NotEavAttribute::class ); } From b2279da535d04bc8f545d8e63d14f4c982d4a7bb Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Thu, 4 Oct 2018 13:19:36 +0300 Subject: [PATCH 278/812] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch - fix static tests --- .../CategoryFieldsProvider.php | 13 +++++------ .../Adapter/DataMapper/ProductDataMapper.php | 23 ++++++++++++++----- .../FieldIndex/IndexResolver.php | 2 +- .../FieldMapper/ProductFieldMapper.php | 11 ++++----- .../Model/Adapter/FieldType.php | 2 ++ .../CategoryFieldsProvider.php | 11 ++++----- .../BatchDataMapper/PriceFieldsProvider.php | 13 +++++------ .../Adapter/DataMapper/ProductDataMapper.php | 2 ++ .../Model/Adapter/Elasticsearch.php | 2 +- .../FieldMapper/Product/AttributeProvider.php | 2 +- .../Product/FieldProvider/DynamicField.php | 2 +- .../FieldIndex/IndexResolver.php | 2 +- .../FieldName/Resolver/CategoryName.php | 2 +- .../FieldName/Resolver/Position.php | 2 +- .../FieldName/Resolver/Price.php | 2 +- .../Elasticsearch/Model/Adapter/FieldType.php | 1 + .../FieldType/Resolver/IntegerTypeTest.php | 3 ++- .../FieldType/Resolver/KeywordTypeTest.php | 6 +++-- .../Annotation/AnnotationFormatValidator.php | 2 +- 19 files changed, 59 insertions(+), 44 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 2ff37dab4fd2d..eb7874a936140 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -10,8 +10,7 @@ use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; use Magento\Framework\App\ObjectManager; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface - as FieldNameResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; /** * Provide data mapping for categories fields @@ -29,29 +28,29 @@ class CategoryFieldsProvider implements AdditionalFieldsProviderInterface private $attributeAdapterProvider; /** - * @var FieldNameResolver + * @var ResolverInterface */ private $fieldNameResolver; /** * @param Index $resourceIndex * @param AttributeProvider|null $attributeAdapterProvider - * @param FieldNameResolver|null $fieldNameResolver + * @param ResolverInterface|null $fieldNameResolver */ public function __construct( Index $resourceIndex, AttributeProvider $attributeAdapterProvider = null, - FieldNameResolver $fieldNameResolver = null + ResolverInterface $fieldNameResolver = null ) { $this->resourceIndex = $resourceIndex; $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() ->get(AttributeProvider::class); $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() - ->get(FieldNameResolver::class); + ->get(ResolverInterface::class); } /** - * {@inheritdoc} + * @inheritdoc */ public function getFields(array $productIds, $storeId) { diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php index 8c4022604afdf..f0b7380397235 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/DataMapper/ProductDataMapper.php @@ -17,10 +17,11 @@ use Magento\Elasticsearch\Model\Adapter\FieldType\Date as DateFieldType; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; use Magento\Framework\App\ObjectManager; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface - as FieldNameResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; /** + * Don't use this product data mapper class. + * * @deprecated 100.2.0 * @see \Magento\Elasticsearch\Model\Adapter\BatchDataMapperInterface */ @@ -89,7 +90,7 @@ class ProductDataMapper implements DataMapperInterface private $attributeAdapterProvider; /** - * @var FieldNameResolver + * @var ResolverInterface */ private $fieldNameResolver; @@ -103,7 +104,7 @@ class ProductDataMapper implements DataMapperInterface * @param StoreManagerInterface $storeManager * @param DateFieldType $dateFieldType * @param AttributeProvider|null $attributeAdapterProvider - * @param FieldNameResolver|null $fieldNameResolver + * @param ResolverInterface|null $fieldNameResolver */ public function __construct( Builder $builder, @@ -113,7 +114,7 @@ public function __construct( StoreManagerInterface $storeManager, DateFieldType $dateFieldType, AttributeProvider $attributeAdapterProvider = null, - FieldNameResolver $fieldNameResolver = null + ResolverInterface $fieldNameResolver = null ) { $this->builder = $builder; $this->attributeContainer = $attributeContainer; @@ -124,7 +125,7 @@ public function __construct( $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() ->get(AttributeProvider::class); $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() - ->get(FieldNameResolver::class); + ->get(ResolverInterface::class); $this->mediaGalleryRoles = [ self::MEDIA_ROLE_IMAGE, @@ -226,6 +227,8 @@ protected function processAdvancedAttributes($productId, array $productIndexData } /** + * Check value. + * * @param mixed $value * @param Attribute $attribute * @param string $storeId @@ -316,6 +319,8 @@ protected function getProductMediaGalleryData($media, $roles) } /** + * Get media role image. + * * @param string $file * @param array $roles * @return string @@ -326,6 +331,8 @@ protected function getMediaRoleImage($file, $roles) } /** + * Get media role small image. + * * @param string $file * @param array $roles * @return string @@ -336,6 +343,8 @@ protected function getMediaRoleSmallImage($file, $roles) } /** + * Get media role thumbnail. + * * @param string $file * @param array $roles * @return string @@ -346,6 +355,8 @@ protected function getMediaRoleThumbnail($file, $roles) } /** + * Get media role swatch image. + * * @param string $file * @param array $roles * @return string diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php index 7812018516151..a7b839c99139d 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -52,7 +52,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getFieldIndex(AttributeAdapter $attribute) { diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php index 463a7770357ad..5aea87e5e6ae1 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/ProductFieldMapper.php @@ -10,8 +10,7 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface - as FieldNameResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; use Magento\Framework\App\ObjectManager; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldType; use Magento\Framework\Registry; @@ -59,7 +58,7 @@ class ProductFieldMapper implements FieldMapperInterface private $attributeAdapterProvider; /** - * @var FieldNameResolver + * @var ResolverInterface */ private $fieldNameResolver; @@ -74,7 +73,7 @@ class ProductFieldMapper implements FieldMapperInterface * @param CustomerSession $customerSession * @param StoreManager $storeManager * @param Registry $coreRegistry - * @param FieldNameResolver|null $fieldNameResolver + * @param ResolverInterface|null $fieldNameResolver * @param AttributeProvider|null $attributeAdapterProvider * @param FieldProviderInterface|null $fieldProvider */ @@ -84,7 +83,7 @@ public function __construct( CustomerSession $customerSession, StoreManager $storeManager, Registry $coreRegistry, - FieldNameResolver $fieldNameResolver = null, + ResolverInterface $fieldNameResolver = null, AttributeProvider $attributeAdapterProvider = null, FieldProviderInterface $fieldProvider = null ) { @@ -94,7 +93,7 @@ public function __construct( $this->storeManager = $storeManager; $this->coreRegistry = $coreRegistry; $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() - ->get(FieldNameResolver::class); + ->get(ResolverInterface::class); $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() ->get(AttributeProvider::class); $this->fieldProvider = $fieldProvider ?: ObjectManager::getInstance() diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php index 002a787fd031a..3b7e79ae88bcd 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldType.php @@ -36,6 +36,8 @@ class FieldType /**#@-*/ /** + * Get field type. + * * @deprecated * @see ResolverInterface::getFieldType * diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index fc557d427feea..108721fd8561f 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -10,8 +10,7 @@ use Magento\AdvancedSearch\Model\Adapter\DataMapper\AdditionalFieldsProviderInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; use Magento\Framework\App\ObjectManager; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface - as FieldNameResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; /** * Provide data mapping for categories fields @@ -29,25 +28,25 @@ class CategoryFieldsProvider implements AdditionalFieldsProviderInterface private $attributeAdapterProvider; /** - * @var FieldNameResolver + * @var ResolverInterface */ private $fieldNameResolver; /** * @param Index $resourceIndex * @param AttributeProvider|null $attributeAdapterProvider - * @param FieldNameResolver|null $fieldNameResolver + * @param ResolverInterface|null $fieldNameResolver */ public function __construct( Index $resourceIndex, AttributeProvider $attributeAdapterProvider = null, - FieldNameResolver $fieldNameResolver = null + ResolverInterface $fieldNameResolver = null ) { $this->resourceIndex = $resourceIndex; $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() ->get(AttributeProvider::class); $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() - ->get(FieldNameResolver::class); + ->get(ResolverInterface::class); } /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php index 1b749fd7039e5..875d384a20596 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/PriceFieldsProvider.php @@ -12,8 +12,7 @@ use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; use Magento\Framework\App\ObjectManager; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface - as FieldNameResolver; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\ResolverInterface; /** * Provide data mapping for price fields @@ -41,7 +40,7 @@ class PriceFieldsProvider implements AdditionalFieldsProviderInterface private $attributeAdapterProvider; /** - * @var FieldNameResolver + * @var ResolverInterface */ private $fieldNameResolver; @@ -50,14 +49,14 @@ class PriceFieldsProvider implements AdditionalFieldsProviderInterface * @param DataProvider $dataProvider * @param StoreManagerInterface $storeManager * @param AttributeProvider|null $attributeAdapterProvider - * @param FieldNameResolver|null $fieldNameResolver + * @param ResolverInterface|null $fieldNameResolver */ public function __construct( Index $resourceIndex, DataProvider $dataProvider, StoreManagerInterface $storeManager, AttributeProvider $attributeAdapterProvider = null, - FieldNameResolver $fieldNameResolver = null + ResolverInterface $fieldNameResolver = null ) { $this->resourceIndex = $resourceIndex; $this->dataProvider = $dataProvider; @@ -65,11 +64,11 @@ public function __construct( $this->attributeAdapterProvider = $attributeAdapterProvider ?: ObjectManager::getInstance() ->get(AttributeProvider::class); $this->fieldNameResolver = $fieldNameResolver ?: ObjectManager::getInstance() - ->get(FieldNameResolver::class); + ->get(ResolverInterface::class); } /** - * {@inheritdoc} + * @inheritdoc */ public function getFields(array $productIds, $storeId) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php index f2082dd5fc243..24b740b554fcb 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/DataMapper/ProductDataMapper.php @@ -9,6 +9,8 @@ use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\DataMapper\ProductDataMapper as ElasticSearch5ProductDataMapper; /** + * Don't use this product data mapper class. + * * @deprecated 100.2.0 * @see \Magento\Elasticsearch\Model\Adapter\BatchDataMapperInterface */ diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php index 8e69001272b27..772868e4e3e59 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/Elasticsearch.php @@ -284,8 +284,8 @@ protected function getDocsArrayInBulkIndexFormat( * Checks whether Elasticsearch index and alias exists. * * @param int $storeId - * @param bool $checkAlias * @param string $mappedIndexerId + * @param bool $checkAlias * @return $this */ public function checkIndex( diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php index bf8afb5e37530..4338f4f1c8492 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php @@ -65,7 +65,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getByAttributeCode(string $attributeCode): AttributeAdapter { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php index 877b81f367f4c..5e1cee9a0c390 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php @@ -91,7 +91,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getFields(array $context = []): array { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php index c5fcf758da325..f6a0b2dfac9fd 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -29,7 +29,7 @@ public function __construct(ConverterInterface $converter) } /** - * {@inheritdoc} + * @inheritdoc */ public function getFieldIndex(AttributeAdapter $attribute) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php index d5e2b09f4ea2c..e248b3098d586 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php @@ -58,7 +58,7 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin } /** - * {@inheritdoc} + * @inheritdoc */ private function resolveCategoryId($context): int { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php index 99c7f82be117e..3869ef8b661c7 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php @@ -54,7 +54,7 @@ public function getFieldName(AttributeAdapter $attribute, $context = []): ?strin } /** - * {@inheritdoc} + * @inheritdoc */ private function resolveCategoryId($context) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php index a7a4d506859c9..4b26d9a8e32a5 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php @@ -42,7 +42,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php index 7ad6539e6b718..97f159d13528d 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldType.php @@ -35,6 +35,7 @@ class FieldType /**#@-*/ /** + * Get field type. * * @deprecated * @see ResolverInterface::getFieldType diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php index 5f419dea1f26a..b5496628b3af9 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -4,7 +4,8 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; +namespace +Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php index be8b2e30e5f4b..84adbdab7acdd 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php @@ -4,10 +4,12 @@ * See COPYING.txt for license details. */ -namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; +namespace +Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; -use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface as FieldTypeConverterInterface; +use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface + as FieldTypeConverterInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType; diff --git a/dev/tests/static/framework/Magento/Sniffs/Annotation/AnnotationFormatValidator.php b/dev/tests/static/framework/Magento/Sniffs/Annotation/AnnotationFormatValidator.php index 71ad99bb5c3e0..899a65c375321 100644 --- a/dev/tests/static/framework/Magento/Sniffs/Annotation/AnnotationFormatValidator.php +++ b/dev/tests/static/framework/Magento/Sniffs/Annotation/AnnotationFormatValidator.php @@ -125,7 +125,7 @@ private function validateShortDescriptionFormat( $phpcsFile->addFixableError($error, $shortPtr, 'MethodAnnotation'); } if (strtolower($tokens[$shortPtr]['content']) === '{@inheritdoc}') { - $error = '{@inheritdoc} imports only short description, annotation must have long description'; + $error = 'If the @inheritdoc not inline it shouldn’t have braces'; $phpcsFile->addFixableError($error, $shortPtr, 'MethodAnnotation'); } $shortPtrContent = $tokens[$shortPtr]['content']; From 4c1b154e980a20afdf49f84d055d66f189aa6d17 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Thu, 4 Oct 2018 14:31:03 +0300 Subject: [PATCH 279/812] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch - fix static tests --- .../FieldMapper/Product/FieldProvider/FieldIndex/Converter.php | 2 ++ .../Product/FieldProvider/FieldIndex/IndexResolver.php | 1 + .../FieldMapper/Product/FieldProvider/FieldType/Converter.php | 2 ++ .../FieldProvider/FieldType/Resolver/CompositeResolver.php | 1 + .../Product/FieldProvider/FieldType/Resolver/IntegerType.php | 1 + .../Product/FieldProvider/FieldType/Resolver/KeywordType.php | 1 + .../Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php | 2 +- .../Model/Adapter/FieldMapper/Product/AttributeAdapter.php | 1 + .../FieldMapper/Product/AttributeAdapter/DummyAttribute.php | 2 ++ .../Model/Adapter/FieldMapper/Product/AttributeProvider.php | 2 ++ .../Adapter/FieldMapper/Product/CompositeFieldProvider.php | 1 + .../Adapter/FieldMapper/Product/FieldProvider/DynamicField.php | 2 ++ .../FieldMapper/Product/FieldProvider/FieldIndex/Converter.php | 2 ++ .../Product/FieldProvider/FieldIndex/ConverterInterface.php | 2 ++ .../Product/FieldProvider/FieldIndex/IndexResolver.php | 1 + .../Product/FieldProvider/FieldIndex/ResolverInterface.php | 1 + .../Product/FieldProvider/FieldName/Resolver/CategoryName.php | 1 + .../FieldProvider/FieldName/Resolver/CompositeResolver.php | 1 + .../FieldProvider/FieldName/Resolver/DefaultResolver.php | 1 + .../FieldProvider/FieldName/Resolver/NotEavAttribute.php | 1 + .../Product/FieldProvider/FieldName/Resolver/Position.php | 3 ++- .../Product/FieldProvider/FieldName/Resolver/Price.php | 1 + .../FieldProvider/FieldName/Resolver/SpecialAttribute.php | 1 + .../Product/FieldProvider/FieldName/ResolverInterface.php | 1 + .../FieldMapper/Product/FieldProvider/FieldType/Converter.php | 2 ++ .../Product/FieldProvider/FieldType/ConverterInterface.php | 2 ++ .../FieldProvider/FieldType/Resolver/CompositeResolver.php | 1 + .../Product/FieldProvider/FieldType/Resolver/DateTimeType.php | 1 + .../FieldProvider/FieldType/Resolver/DefaultResolver.php | 1 + .../Product/FieldProvider/FieldType/Resolver/FloatType.php | 1 + .../Product/FieldProvider/FieldType/Resolver/IntegerType.php | 1 + .../Product/FieldProvider/FieldType/ResolverInterface.php | 1 + .../Adapter/FieldMapper/Product/FieldProvider/StaticField.php | 2 ++ .../Adapter/FieldMapper/Product/FieldProviderInterface.php | 2 ++ .../Product/FieldProvider/FieldIndex/IndexResolverTest.php | 1 + .../FieldProvider/FieldType/Resolver/IntegerTypeTest.php | 1 + .../FieldProvider/FieldType/Resolver/KeywordTypeTest.php | 1 + .../Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php | 1 + .../FieldMapper/Product/FieldProvider/DynamicFieldTest.php | 1 + .../Product/FieldProvider/FieldIndex/IndexResolverTest.php | 1 + .../FieldProvider/FieldName/Resolver/CategoryNameTest.php | 1 + .../FieldProvider/FieldName/Resolver/DefaultResolverTest.php | 1 + .../FieldProvider/FieldName/Resolver/NotEavAttributeTest.php | 1 + .../Product/FieldProvider/FieldName/Resolver/PositionTest.php | 1 + .../Product/FieldProvider/FieldName/Resolver/PriceTest.php | 1 + .../FieldProvider/FieldName/Resolver/SpecialAttributeTest.php | 1 + .../Product/FieldProvider/FieldType/ConverterTest.php | 1 + .../FieldProvider/FieldType/Resolver/DateTimeTypeTest.php | 1 + .../FieldProvider/FieldType/Resolver/DefaultResolverTest.php | 1 + .../Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php | 1 + .../FieldProvider/FieldType/Resolver/IntegerTypeTest.php | 1 + .../FieldMapper/Product/FieldProvider/StaticFieldTest.php | 1 + 52 files changed, 64 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php index a5969f58c27f9..b7f21696162dd 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface; diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php index a7b839c99139d..954deaec639ef 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php index ae9db7c5c348e..1f6e05c9e02fc 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface; diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index bcc6a430e6fa3..fed36ff6b1c8f 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php index d0ddd6115e557..e5c8dd48c7af3 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php index e27376f415610..e522d4ae5e070 100644 --- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php +++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php index 108721fd8561f..0e130c24e79d3 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/CategoryFieldsProvider.php @@ -50,7 +50,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getFields(array $productIds, $storeId) { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php index 6cfe4a256b11c..17ebf9c83903e 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php index 85e8722627c2b..b8c0da53c53e0 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeAdapter/DummyAttribute.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeAdapter; use Magento\Framework\Api\CustomAttributesDataInterface; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php index 4338f4f1c8492..89c98d29ae03e 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/AttributeProvider.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; use Magento\Eav\Model\Config; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php index f1622a900c7b3..8038c8c05bc1c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/CompositeFieldProvider.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php index 5e1cee9a0c390..c7e2a4beabb5c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider; use Magento\Catalog\Api\CategoryListInterface; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php index bbe72821671dc..5abe4972e34d0 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/Converter.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php index 968f73e2b5d92..02c4d29558dad 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ConverterInterface.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php index f6a0b2dfac9fd..590430a7e2431 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php index fb87e0756d621..663b1d865fb52 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/ResolverInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php index e248b3098d586..bc91f04ee380e 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php index 5f48cc8b1a529..f1fed3f06fe35 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CompositeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php index b3f1a1d716557..3208ca7fc6171 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php index d92730595abfd..cbbd15083ee60 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttribute.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php index 3869ef8b661c7..044d5d8da9a6c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Position.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; @@ -42,7 +43,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getFieldName(AttributeAdapter $attribute, $context = []): ?string { diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php index 4b26d9a8e32a5..12e53ca2bd714 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/Price.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php index 813c6c71c9d1a..4fa16db98639e 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttribute.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php index ecc46d2607cf8..3d36e026f70db 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/ResolverInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php index 147abc893eba3..88dab83698794 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Converter.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php index e5ec1ce445ab2..3e7c3e9b592bd 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterInterface.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; /** diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php index e2a0025625b93..e83502e4fe32e 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/CompositeResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php index 3430288f59405..a4e3c634ce717 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php index 894834f30b47c..be4a8cca28814 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolver.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php index e45989b54b921..a6681a7f676ba 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php index 3fa24b3b2af56..7793f60cd1efc 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerType.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php index 118a440cddef2..43e512ecb025b 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ResolverInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php index d15040f24d775..b5c78cbc28f45 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/StaticField.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider; use Magento\Eav\Model\Config; diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php index 2a68e3e2a3708..aaafb699b33bd 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProviderInterface.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Elasticsearch\Model\Adapter\FieldMapper\Product; /** diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php index 9b0159332d691..98284e49ad85d 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php index b5496628b3af9..39155e4f4fe02 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php index 84adbdab7acdd..0e33498a16fba 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/KeywordTypeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php index 39543150dd849..9ca65d8e675b9 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/AttributeAdapterTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php index b62fab78e6a0e..ba5e97aa14b54 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicFieldTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php index 96cebfe408db5..86bcfeb06480e 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldIndex/IndexResolverTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php index 1cdeb0ac867b4..5ebeac2284435 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryNameTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php index 3d2ecadd28463..4fa99f3bf834d 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/DefaultResolverTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php index fbf7479d9aa1f..cdd8dde585a5a 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/NotEavAttributeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php index 104db78d3c08f..dcfd4d02988da 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PositionTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php index 584b7bf95f41c..244da5a42e00a 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/PriceTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php index 6efd7acee665a..dcbf64bbb2005 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/SpecialAttributeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php index 1a0fb93441ae7..842007aee294e 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/ConverterTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php index 34c36bd456dfe..ca474c4bee17d 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DateTimeTypeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php index e086a959bdde7..72b5320a050bd 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/DefaultResolverTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php index 435883c847b3c..c69a6f35b1eb4 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/FloatTypeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php index bb111f5f5f97a..7570c8971b27b 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/FieldType/Resolver/IntegerTypeTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php index 0937bc570a1d5..bf8b601ed43ab 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/FieldMapper/Product/FieldProvider/StaticFieldTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Elasticsearch\Test\Unit\Model\Adapter\FieldMapper\Product\FieldProvider; From 061af74816ee715eaf312b18a94ca3f30818eb59 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Thu, 4 Oct 2018 15:09:05 +0300 Subject: [PATCH 280/812] MAGETWO-94482: [2.3] Fixed procedure of creating mapping for dynamic fields in elasticsearch - fix static tests --- .../Product/FieldProvider/FieldName/Resolver/CategoryName.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php index bc91f04ee380e..5824aca6cdd54 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/FieldName/Resolver/CategoryName.php @@ -71,6 +71,6 @@ private function resolveCategoryId($context): int : $this->storeManager->getStore()->getRootCategoryId(); } - return $id; + return (int)$id; } } From 93b8f297f0890a88deb52e8baefb09af1bed8abf Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Fri, 12 Oct 2018 14:03:11 +0300 Subject: [PATCH 281/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fix static tests --- .../Block/Product/ProductList/Toolbar.php | 14 ++++++++++++++ .../view/frontend/web/js/product/list/toolbar.js | 16 ++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index 12c691d1365c3..c7a9fcce7bf7a 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -430,6 +430,8 @@ public function getPagerUrl($params = []) } /** + * Get pager encoded url. + * * @param array $params * @return string */ @@ -624,6 +626,8 @@ public function getLimit() } /** + * Check if limit is current used in toolbar. + * * @param int $limit * @return bool */ @@ -633,6 +637,8 @@ public function isLimitCurrent($limit) } /** + * Pager number of items from which products started on current page. + * * @return int */ public function getFirstNum() @@ -642,6 +648,8 @@ public function getFirstNum() } /** + * Pager number of items products finished on current page. + * * @return int */ public function getLastNum() @@ -651,6 +659,8 @@ public function getLastNum() } /** + * Total number of products in current category. + * * @return int */ public function getTotalNum() @@ -659,6 +669,8 @@ public function getTotalNum() } /** + * Check if current page is the first. + * * @return bool */ public function isFirstPage() @@ -667,6 +679,8 @@ public function isFirstPage() } /** + * Return last page number. + * * @return int */ public function getLastPageNum() diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index 7c47f5bd04d5a..b8b6ff65be2b4 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -91,7 +91,7 @@ define([ baseUrl = urlPaths[0], urlParams = urlPaths[1] ? urlPaths[1].split('&') : [], paramData = {}, - parameters, i; + parameters, i, form, params, key, input, formKey; for (i = 0; i < urlParams.length; i++) { parameters = urlParams[i].split('='); @@ -102,25 +102,25 @@ define([ paramData[paramName] = paramValue; if (this.options.post) { - var form = document.createElement('form'); + form = document.createElement('form'); + params = [this.options.mode, this.options.direction, this.options.order, this.options.limit]; - var params = [this.options.mode, this.options.direction, this.options.order, this.options.limit]; - for (var key in paramData) { - if (params.indexOf(key) !== -1) { - var input = document.createElement('input'); + for (key in paramData) { + if (params.indexOf(key) !== -1) { //eslint-disable-line max-depth + input = document.createElement('input'); input.name = key; input.value = paramData[key]; form.appendChild(input); delete paramData[key]; } } - var formKey = document.createElement('input'); + formKey = document.createElement('input'); formKey.name = 'form_key'; formKey.value = this.options.formKey; form.appendChild(formKey); paramData = $.param(paramData); - baseUrl = baseUrl + (paramData.length ? '?' + paramData : ''); + baseUrl += paramData.length ? '?' + paramData : ''; form.action = baseUrl; form.method = 'POST'; From 2e1d92f89e413f02c2e23b2c9e19870cf3a8e229 Mon Sep 17 00:00:00 2001 From: Alexey Arendarenko <alexeya@ven.com> Date: Fri, 12 Oct 2018 15:06:28 +0300 Subject: [PATCH 282/812] Update newsletter module Update module logic when customer have store_id = 0 --- .../Model/ResourceModel/Subscriber.php | 23 ++++++++++++++++--- .../Magento/Newsletter/Model/Subscriber.php | 11 +++++---- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php b/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php index b6e53b3695f78..57123d6842647 100644 --- a/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php @@ -5,6 +5,9 @@ */ namespace Magento\Newsletter\Model\ResourceModel; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\App\ObjectManager; + /** * Newsletter subscriber resource model * @@ -48,6 +51,13 @@ class Subscriber extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ protected $mathRandom; + /** + * Store manager + * + * @var StoreManagerInterface + */ + private $storeManager; + /** * Construct * @@ -55,15 +65,19 @@ class Subscriber extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb * @param \Magento\Framework\Stdlib\DateTime\DateTime $date * @param \Magento\Framework\Math\Random $mathRandom * @param string $connectionName + * @param StoreManagerInterface $storeManager */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, \Magento\Framework\Stdlib\DateTime\DateTime $date, \Magento\Framework\Math\Random $mathRandom, - $connectionName = null + $connectionName = null, + StoreManagerInterface $storeManager = null ) { $this->_date = $date; $this->mathRandom = $mathRandom; + $this->storeManager = $storeManager ?: ObjectManager::getInstance() + ->get(StoreManagerInterface::class); parent::__construct($context, $connectionName); } @@ -117,6 +131,9 @@ public function loadByEmail($subscriberEmail) */ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface $customer) { + $storeId = (int)$customer->getStoreId() ?: $this->storeManager + ->getWebsite($customer->getWebsiteId())->getDefaultStore()->getId(); + $select = $this->connection ->select() ->from($this->getMainTable()) @@ -127,7 +144,7 @@ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface $select, [ 'customer_id' => $customer->getId(), - 'store_id' => $customer->getStoreId() + 'store_id' => $storeId ] ); @@ -145,7 +162,7 @@ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface $select, [ 'subscriber_email' => $customer->getEmail(), - 'store_id' => $customer->getStoreId() + 'store_id' => $storeId ] ); diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php index 03976dfcdc197..5527060a6e2f1 100644 --- a/app/code/Magento/Newsletter/Model/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/Subscriber.php @@ -613,16 +613,17 @@ protected function _updateCustomerSubscription($customerId, $subscribe) $this->setStatus($status); + $storeId = $customerData->getStoreId(); + if ((int)$customerData->getStoreId() === 0) { + $storeId = $this->_storeManager->getWebsite($customerData->getWebsiteId())->getDefaultStore()->getId(); + } + if (!$this->getId()) { - $storeId = $customerData->getStoreId(); - if ($customerData->getStoreId() == 0) { - $storeId = $this->_storeManager->getWebsite($customerData->getWebsiteId())->getDefaultStore()->getId(); - } $this->setStoreId($storeId) ->setCustomerId($customerData->getId()) ->setEmail($customerData->getEmail()); } else { - $this->setStoreId($customerData->getStoreId()) + $this->setStoreId($storeId) ->setEmail($customerData->getEmail()); } From d3827507fa21d4cdc4b02c0b87ede4bf72ce980e Mon Sep 17 00:00:00 2001 From: Alexey Arendarenko <alexeya@ven.com> Date: Fri, 12 Oct 2018 15:07:02 +0300 Subject: [PATCH 283/812] Update newsletter module Fix unit tests according to new logic Add integration tests for case when customer have store_id = 0 --- .../Test/Unit/Model/SubscriberTest.php | 15 +++++--- .../Newsletter/Model/Plugin/PluginTest.php | 38 +++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php index 9809a9ee4e430..6ccbba9f8828b 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php @@ -213,6 +213,7 @@ public function testSubscribeNotLoggedIn() public function testUpdateSubscription() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -234,7 +235,7 @@ public function testUpdateSubscription() ->method('getConfirmationStatus') ->with($customerId) ->willReturn('account_confirmation_required'); - $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id'); + $customerDataMock->expects($this->exactly(2))->method('getStoreId')->willReturn($storeId); $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email'); $storeModel = $this->getMockBuilder(\Magento\Store\Model\Store::class) @@ -248,6 +249,7 @@ public function testUpdateSubscription() public function testUnsubscribeCustomerById() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -265,7 +267,7 @@ public function testUnsubscribeCustomerById() ); $customerDataMock->expects($this->atLeastOnce())->method('getId')->willReturn('id'); $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf(); - $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id'); + $customerDataMock->expects($this->exactly(2))->method('getStoreId')->willReturn($storeId); $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email'); $this->sendEmailCheck(); @@ -274,6 +276,7 @@ public function testUnsubscribeCustomerById() public function testSubscribeCustomerById() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -291,7 +294,7 @@ public function testSubscribeCustomerById() ); $customerDataMock->expects($this->atLeastOnce())->method('getId')->willReturn('id'); $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf(); - $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id'); + $customerDataMock->expects($this->exactly(2))->method('getStoreId')->willReturn($storeId); $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email'); $this->sendEmailCheck(); @@ -300,6 +303,7 @@ public function testSubscribeCustomerById() public function testSubscribeCustomerById1() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -317,7 +321,7 @@ public function testSubscribeCustomerById1() ); $customerDataMock->expects($this->atLeastOnce())->method('getId')->willReturn('id'); $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf(); - $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id'); + $customerDataMock->expects($this->exactly(2))->method('getStoreId')->willReturn($storeId); $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email'); $this->sendEmailCheck(); $this->customerAccountManagement->expects($this->once()) @@ -331,6 +335,7 @@ public function testSubscribeCustomerById1() public function testSubscribeCustomerByIdAfterConfirmation() { + $storeId = 2; $customerId = 1; $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); @@ -348,7 +353,7 @@ public function testSubscribeCustomerByIdAfterConfirmation() ); $customerDataMock->expects($this->atLeastOnce())->method('getId')->willReturn('id'); $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf(); - $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id'); + $customerDataMock->expects($this->exactly(2))->method('getStoreId')->willReturn($storeId); $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email'); $this->sendEmailCheck(); $this->customerAccountManagement->expects($this->never())->method('getConfirmationStatus'); diff --git a/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php b/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php index 39db400d2d637..dbc666e49b6cf 100644 --- a/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php +++ b/dev/tests/integration/testsuite/Magento/Newsletter/Model/Plugin/PluginTest.php @@ -167,4 +167,42 @@ private function verifySubscriptionNotExist($email) $this->assertEquals(0, (int)$subscriber->getId()); return $subscriber; } + + /** + * @magentoAppArea adminhtml + * @magentoDbIsolation enabled + */ + public function testCustomerWithZeroStoreIdIsSubscribed() + { + $objectManager = Bootstrap::getObjectManager(); + + $currentStore = $objectManager->get( + \Magento\Store\Model\StoreManagerInterface::class + )->getStore()->getId(); + + $subscriber = $objectManager->create(\Magento\Newsletter\Model\Subscriber::class); + /** @var \Magento\Newsletter\Model\Subscriber $subscriber */ + $subscriber->setStoreId($currentStore) + ->setCustomerId(0) + ->setSubscriberEmail('customer@example.com') + ->setSubscriberStatus(\Magento\Newsletter\Model\Subscriber::STATUS_SUBSCRIBED) + ->save(); + + /** @var \Magento\Customer\Api\Data\CustomerInterfaceFactory $customerFactory */ + $customerFactory = $objectManager->get(\Magento\Customer\Api\Data\CustomerInterfaceFactory::class); + $customerDataObject = $customerFactory->create() + ->setFirstname('Firstname') + ->setLastname('Lastname') + ->setStoreId(0) + ->setEmail('customer@example.com'); + /** @var \Magento\Customer\Api\Data\CustomerInterface $customer */ + $customer = $this->accountManagement->createAccount($customerDataObject); + + $this->customerRepository->save($customer); + + $subscriber->loadByEmail('customer@example.com'); + + $this->assertEquals($customer->getId(), (int)$subscriber->getCustomerId()); + $this->assertEquals($currentStore, (int)$subscriber->getStoreId()); + } } From a169f5c4b780bf6eae65f2ac40accbaca1ef7be3 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Fri, 12 Oct 2018 15:21:54 +0300 Subject: [PATCH 284/812] MAGETWO-95694: Issue with Magento upgrade within Web Setup Wizard --- setup/pub/magento/setup/app.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/pub/magento/setup/app.js b/setup/pub/magento/setup/app.js index b433e3f19c8bf..f0abd15d106c2 100644 --- a/setup/pub/magento/setup/app.js +++ b/setup/pub/magento/setup/app.js @@ -56,6 +56,9 @@ app.config(['$httpProvider', '$stateProvider', function ($httpProvider, $statePr return $delegate; }); }) + .config(['$locationProvider', function($locationProvider) { + $locationProvider.hashPrefix(''); + }]) .run(function ($rootScope, $state) { $rootScope.$state = $state; }); From 88f99b2f23e285a6e9ae0a0eab7ac8bbbe5f66a7 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 12 Oct 2018 15:27:53 +0300 Subject: [PATCH 285/812] MAGETWO-92163: Redundancy in Custom Option Filenames --- .../Magento/Wishlist/Controller/Index/DownloadCustomOption.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php index 9ffec68780aa1..b87afa8e5d0c4 100644 --- a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php +++ b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php @@ -6,6 +6,7 @@ namespace Magento\Wishlist\Controller\Index; use Magento\Framework\App\Action; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\App\ObjectManager; use Magento\Framework\Controller\ResultFactory; @@ -14,7 +15,7 @@ /** * Class DownloadCustomOption. Represents request-flow logic for option's file download */ -class DownloadCustomOption extends \Magento\Wishlist\Controller\AbstractIndex +class DownloadCustomOption extends \Magento\Wishlist\Controller\AbstractIndex implements HttpGetActionInterface { /** * @var \Magento\Framework\App\Response\Http\FileFactory From 9c01411858079ff9c12b968ea8d681f6edad39b7 Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Thu, 14 Jun 2018 09:48:26 +0200 Subject: [PATCH 286/812] Fix typehint of customer-data updateSectionId parameters The typehint wrongly indicates the parameter should be a number, where in fact it is a boolean. It is passed through to the server side to the controller action \Magento\Customer\Controller\Section\Load::execute() where it is cast to a boolean and passed as the $updateIds parameter to \Magento\Customer\CustomerData\SectionPool::getSectionsData() and from there as the boolean parameter $forceUpdate to the \Magento\Customer\CustomerData\Section\Identifier::initMark() method. This PR introduces no backward incompatibilities, it only fixes the type hint to make the code more readable and improve compatibility with static code analysis tools. --- .../Magento/Customer/view/frontend/web/js/customer-data.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js index cfa06c6e12003..8cbc779a99ab0 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js +++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js @@ -75,7 +75,7 @@ define([ /** * @param {Object} sectionNames - * @param {Number} updateSectionId + * @param {Boolean} updateSectionId * @return {*} */ getFromServer: function (sectionNames, updateSectionId) { @@ -326,7 +326,7 @@ define([ /** * @param {Array} sectionNames - * @param {Number} updateSectionId + * @param {Boolean} updateSectionId * @return {*} */ reload: function (sectionNames, updateSectionId) { From 696a0c22dac2b426c0685d9b626c323fd62709b1 Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Sat, 16 Jun 2018 20:51:24 +0200 Subject: [PATCH 287/812] Rename parameter variable to make intent more easy to understand. --- .../Customer/view/frontend/web/js/customer-data.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js index 8cbc779a99ab0..07d08847aa4ea 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js +++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js @@ -75,17 +75,17 @@ define([ /** * @param {Object} sectionNames - * @param {Boolean} updateSectionId + * @param {Boolean} forceNewSectionTimestamp * @return {*} */ - getFromServer: function (sectionNames, updateSectionId) { + getFromServer: function (sectionNames, forceNewSectionTimestamp) { var parameters; sectionNames = sectionConfig.filterClientSideSections(sectionNames); parameters = _.isArray(sectionNames) ? { sections: sectionNames.join(',') } : []; - parameters['update_section_id'] = updateSectionId; + parameters['update_section_id'] = forceNewSectionTimestamp; return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) { throw new Error(jqXHR); @@ -326,11 +326,11 @@ define([ /** * @param {Array} sectionNames - * @param {Boolean} updateSectionId + * @param {Boolean} forceNewSectionTimestamp * @return {*} */ - reload: function (sectionNames, updateSectionId) { - return dataProvider.getFromServer(sectionNames, updateSectionId).done(function (sections) { + reload: function (sectionNames, forceNewSectionTimestamp) { + return dataProvider.getFromServer(sectionNames, forceNewSectionTimestamp).done(function (sections) { $(document).trigger('customer-data-reload', [sectionNames]); buffer.update(sections); }); From 3621c3c9b72278c8fd0b95c88eb9b9475dd4b51e Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Fri, 22 Jun 2018 08:47:36 -0400 Subject: [PATCH 288/812] Rename request parameter and variables to make them more expressive --- .../Customer/Controller/Section/Load.php | 8 +++---- .../CustomerData/Section/Identifier.php | 14 +++++------ .../Customer/CustomerData/SectionPool.php | 4 ++-- .../CustomerData/SectionPoolInterface.php | 4 ++-- .../Test/Unit/Controller/Section/LoadTest.php | 24 +++++++++---------- .../Unit/CustomerData/SectionPoolTest.php | 2 +- .../view/frontend/web/js/customer-data.js | 2 +- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Section/Load.php b/app/code/Magento/Customer/Controller/Section/Load.php index e55b1d0df26c7..89d4417c79c19 100644 --- a/app/code/Magento/Customer/Controller/Section/Load.php +++ b/app/code/Magento/Customer/Controller/Section/Load.php @@ -71,11 +71,11 @@ public function execute() $sectionNames = $this->getRequest()->getParam('sections'); $sectionNames = $sectionNames ? array_unique(\explode(',', $sectionNames)) : null; - $updateSectionId = $this->getRequest()->getParam('update_section_id'); - if ('false' === $updateSectionId) { - $updateSectionId = false; + $forceNewSectionTimestamp = $this->getRequest()->getParam('force_new_section_timestamp'); + if ('false' === $forceNewSectionTimestamp) { + $forceNewSectionTimestamp = false; } - $response = $this->sectionPool->getSectionsData($sectionNames, (bool)$updateSectionId); + $response = $this->sectionPool->getSectionsData($sectionNames, (bool)$forceNewSectionTimestamp); } catch (\Exception $e) { $resultJson->setStatusHeader( \Zend\Http\Response::STATUS_CODE_400, diff --git a/app/code/Magento/Customer/CustomerData/Section/Identifier.php b/app/code/Magento/Customer/CustomerData/Section/Identifier.php index 2a770925d1c37..54d7cee2d90bd 100644 --- a/app/code/Magento/Customer/CustomerData/Section/Identifier.php +++ b/app/code/Magento/Customer/CustomerData/Section/Identifier.php @@ -43,12 +43,12 @@ public function __construct( /** * Init mark(identifier) for sections * - * @param bool $forceUpdate + * @param bool $forceNewTimestamp * @return int */ - public function initMark($forceUpdate) + public function initMark($forceNewTimestamp) { - if ($forceUpdate) { + if ($forceNewTimestamp) { $this->markId = time(); return $this->markId; } @@ -68,18 +68,18 @@ public function initMark($forceUpdate) * * @param array $sectionsData * @param null $sectionNames - * @param bool $updateIds + * @param bool $forceNewTimestamp * @return array */ - public function markSections(array $sectionsData, $sectionNames = null, $updateIds = false) + public function markSections(array $sectionsData, $sectionNames = null, $forceNewTimestamp = false) { if (!$sectionNames) { $sectionNames = array_keys($sectionsData); } - $markId = $this->initMark($updateIds); + $markId = $this->initMark($forceNewTimestamp); foreach ($sectionNames as $name) { - if ($updateIds || !array_key_exists(self::SECTION_KEY, $sectionsData[$name])) { + if ($forceNewTimestamp || !array_key_exists(self::SECTION_KEY, $sectionsData[$name])) { $sectionsData[$name][self::SECTION_KEY] = $markId; } } diff --git a/app/code/Magento/Customer/CustomerData/SectionPool.php b/app/code/Magento/Customer/CustomerData/SectionPool.php index 0e0d7b992e33a..618d52079973d 100644 --- a/app/code/Magento/Customer/CustomerData/SectionPool.php +++ b/app/code/Magento/Customer/CustomerData/SectionPool.php @@ -55,10 +55,10 @@ public function __construct( /** * {@inheritdoc} */ - public function getSectionsData(array $sectionNames = null, $updateIds = false) + public function getSectionsData(array $sectionNames = null, $forceNewTimestamp = false) { $sectionsData = $sectionNames ? $this->getSectionDataByNames($sectionNames) : $this->getAllSectionData(); - $sectionsData = $this->identifier->markSections($sectionsData, $sectionNames, $updateIds); + $sectionsData = $this->identifier->markSections($sectionsData, $sectionNames, $forceNewTimestamp); return $sectionsData; } diff --git a/app/code/Magento/Customer/CustomerData/SectionPoolInterface.php b/app/code/Magento/Customer/CustomerData/SectionPoolInterface.php index c308804fd0f8d..ad73b9722b133 100644 --- a/app/code/Magento/Customer/CustomerData/SectionPoolInterface.php +++ b/app/code/Magento/Customer/CustomerData/SectionPoolInterface.php @@ -14,8 +14,8 @@ interface SectionPoolInterface * Get section data by section names. If $sectionNames is null then return all sections data * * @param array $sectionNames - * @param bool $updateIds + * @param bool $forceNewTimestamp * @return array */ - public function getSectionsData(array $sectionNames = null, $updateIds = false); + public function getSectionsData(array $sectionNames = null, $forceNewTimestamp = false); } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Section/LoadTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Section/LoadTest.php index f4bf184f9ebf2..5a7cf42be2c7e 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Section/LoadTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Section/LoadTest.php @@ -83,13 +83,13 @@ protected function setUp() } /** - * @param $sectionNames - * @param $updateSectionID - * @param $sectionNamesAsArray - * @param $updateIds + * @param string $sectionNames + * @param bool $forceNewSectionTimestamp + * @param string[] $sectionNamesAsArray + * @param bool $forceNewTimestamp * @dataProvider executeDataProvider */ - public function testExecute($sectionNames, $updateSectionID, $sectionNamesAsArray, $updateIds) + public function testExecute($sectionNames, $forceNewSectionTimestamp, $sectionNamesAsArray, $forceNewTimestamp) { $this->resultJsonFactoryMock->expects($this->once()) ->method('create') @@ -103,12 +103,12 @@ public function testExecute($sectionNames, $updateSectionID, $sectionNamesAsArra $this->httpRequestMock->expects($this->exactly(2)) ->method('getParam') - ->withConsecutive(['sections'], ['update_section_id']) - ->willReturnOnConsecutiveCalls($sectionNames, $updateSectionID); + ->withConsecutive(['sections'], ['force_new_section_timestamp']) + ->willReturnOnConsecutiveCalls($sectionNames, $forceNewSectionTimestamp); $this->sectionPoolMock->expects($this->once()) ->method('getSectionsData') - ->with($sectionNamesAsArray, $updateIds) + ->with($sectionNamesAsArray, $forceNewTimestamp) ->willReturn([ 'message' => 'some message', 'someKey' => 'someValue' @@ -133,15 +133,15 @@ public function executeDataProvider() return [ [ 'sectionNames' => 'sectionName1,sectionName2,sectionName3', - 'updateSectionID' => 'updateSectionID', + 'forceNewSectionTimestamp' => 'forceNewSectionTimestamp', 'sectionNamesAsArray' => ['sectionName1', 'sectionName2', 'sectionName3'], - 'updateIds' => true + 'forceNewTimestamp' => true ], [ 'sectionNames' => null, - 'updateSectionID' => null, + 'forceNewSectionTimestamp' => null, 'sectionNamesAsArray' => null, - 'updateIds' => false + 'forceNewTimestamp' => false ], ]; } diff --git a/app/code/Magento/Customer/Test/Unit/CustomerData/SectionPoolTest.php b/app/code/Magento/Customer/Test/Unit/CustomerData/SectionPoolTest.php index 98fee70e335f7..2b67df1aee292 100644 --- a/app/code/Magento/Customer/Test/Unit/CustomerData/SectionPoolTest.php +++ b/app/code/Magento/Customer/Test/Unit/CustomerData/SectionPoolTest.php @@ -63,7 +63,7 @@ public function testGetSectionsDataAllSections() $this->identifierMock->expects($this->once()) ->method('markSections') - //check also default value for $updateIds = false + //check also default value for $forceTimestamp = false ->with($allSectionsData, $sectionNames, false) ->willReturn($identifierResult); $modelResult = $this->model->getSectionsData($sectionNames); diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js index 07d08847aa4ea..39e3f8d95ee3b 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js +++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js @@ -85,7 +85,7 @@ define([ parameters = _.isArray(sectionNames) ? { sections: sectionNames.join(',') } : []; - parameters['update_section_id'] = forceNewSectionTimestamp; + parameters['force_new_section_timestamp'] = forceNewSectionTimestamp; return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) { throw new Error(jqXHR); From c404de46a22640bfe844d9bbc63c28fe0ea0bffc Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Sat, 23 Jun 2018 17:40:12 +0200 Subject: [PATCH 289/812] Update query parameter name in performance toolkit to match new name in code --- setup/performance-toolkit/benchmark.jmx | 76 ++++++++++---------- setup/performance-toolkit/benchmark_2015.jmx | 36 +++++----- 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx index 8b295c9f5fc46..e8e033fe59024 100644 --- a/setup/performance-toolkit/benchmark.jmx +++ b/setup/performance-toolkit/benchmark.jmx @@ -2881,12 +2881,12 @@ vars.put("customer_email", customerUser); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -4906,12 +4906,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -5272,12 +5272,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -5566,12 +5566,12 @@ vars.put("customer_email", customerUser); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -5739,12 +5739,12 @@ vars.put("product_sku", product.get("sku")); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -6171,12 +6171,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -6349,12 +6349,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -6787,12 +6787,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -7153,12 +7153,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -7869,12 +7869,12 @@ vars.put("customer_email", customerUser); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -8105,12 +8105,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -8471,12 +8471,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -9146,12 +9146,12 @@ vars.put("customer_email", customerUser); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -9330,12 +9330,12 @@ vars.put("product_sku", product.get("sku")); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -9662,12 +9662,12 @@ vars.put("customer_email", customerUser); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -9929,12 +9929,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -10295,12 +10295,12 @@ vars.put("totalProductsAdded", String.valueOf(productsAdded)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -10492,12 +10492,12 @@ vars.put("item_id", vars.get("cart_items_qty_inputs_" + id)); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> @@ -10813,12 +10813,12 @@ vars.put("customer_email", customerUser); <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">false</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> diff --git a/setup/performance-toolkit/benchmark_2015.jmx b/setup/performance-toolkit/benchmark_2015.jmx index 8be7749a08bc4..e58e610304199 100644 --- a/setup/performance-toolkit/benchmark_2015.jmx +++ b/setup/performance-toolkit/benchmark_2015.jmx @@ -2981,12 +2981,12 @@ vars.put("loadType", "Guest");</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> @@ -3217,12 +3217,12 @@ vars.put("loadType", "Guest");</stringProp> <stringProp name="Argument.name">sections</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> @@ -3565,12 +3565,12 @@ vars.put("loadType", "Guest");</stringProp> <stringProp name="Argument.name">sections</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> @@ -4039,12 +4039,12 @@ vars.put("loadType", "Guest");</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> @@ -4275,12 +4275,12 @@ vars.put("loadType", "Guest");</stringProp> <stringProp name="Argument.name">sections</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> @@ -4623,12 +4623,12 @@ vars.put("loadType", "Guest");</stringProp> <stringProp name="Argument.name">sections</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> @@ -5637,12 +5637,12 @@ vars.put("loadType", "Customer");</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> <stringProp name="Argument.name">sections</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> @@ -5873,12 +5873,12 @@ vars.put("loadType", "Customer");</stringProp> <stringProp name="Argument.name">sections</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> @@ -6221,12 +6221,12 @@ vars.put("loadType", "Customer");</stringProp> <stringProp name="Argument.name">sections</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> - <elementProp name="update_section_id" elementType="HTTPArgument"> + <elementProp name="force_new_section_timestamp" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">true</boolProp> <stringProp name="Argument.value">true</stringProp> <stringProp name="Argument.metadata">=</stringProp> <boolProp name="HTTPArgument.use_equals">true</boolProp> - <stringProp name="Argument.name">update_section_id</stringProp> + <stringProp name="Argument.name">force_new_section_timestamp</stringProp> <stringProp name="Argument.desc">true</stringProp> </elementProp> <elementProp name="_" elementType="HTTPArgument"> From e1e201658be5c247334ef761ac028717cfe0b8a6 Mon Sep 17 00:00:00 2001 From: roman <rleshchenko@magento.com> Date: Fri, 12 Oct 2018 15:48:14 +0300 Subject: [PATCH 290/812] MAGETWO-92163: Redundancy in Custom Option Filenames --- .../Catalog/Model/Product/Option/Type/File/ExistingValidate.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php index 8d4aea135eabb..c9afdf023b307 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php +++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File/ExistingValidate.php @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Model\Product\Option\Type\File; /** From 12753a6f9c73ed4ba3b14a6f94b43c81ea5e2ece Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Fri, 12 Oct 2018 09:55:49 -0500 Subject: [PATCH 291/812] MQE-1304: MFTF test failures between 5pm PDT and midnight PDT - Use generateDate -1 day instead of 01/01/2018 --- .../SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml | 3 ++- .../Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml | 3 ++- .../Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml | 3 ++- .../Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml | 3 ++- .../Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml | 3 ++- .../Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml | 3 ++- .../Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml | 3 ++- .../Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml | 3 ++- .../Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml | 3 ++- .../SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml | 3 ++- .../Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml | 3 ++- 11 files changed, 22 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml index 51062da6f2efe..92d221de9e157 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml @@ -40,7 +40,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Buy X get Y free (discount amount is Y)" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="1" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml index 44145f9290457..3deb688de9c34 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml @@ -42,7 +42,8 @@ <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> <fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="{{_defaultCoupon.code}}" stepKey="fillCouponCode"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="5" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml index a9083cb320ccb..ec835384a52f8 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml @@ -42,7 +42,8 @@ <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> <checkOption selector="{{AdminCartPriceRulesFormSection.useAutoGeneration}}" stepKey="tickAutoGeneration"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="0.99" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml index 9d95b01b2f81d..08a08275ee07a 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml @@ -40,7 +40,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="10" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml index 1adf2d22be4db..a39530f7607e4 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml @@ -40,7 +40,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="19.99" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml index 42d84f13b9acf..1f7d849ac02b0 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml @@ -40,7 +40,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="NOT LOGGED IN" stepKey="selectCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Percent of product price discount" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="50" stepKey="fillDiscountAmount"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml index e8b8c6cd9e683..3eec020e26347 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml @@ -43,7 +43,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml index ae7d0eed739ff..73b5d2546f439 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml @@ -43,7 +43,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml index c43aaf8d3c97c..51d11b4e5cb1c 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantity.xml @@ -43,7 +43,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml index 4e1944bed9b42..9395e87c20edb 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml @@ -43,7 +43,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml index 8fb27a9dd1ef3..7c9c52e1c02ac 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotal.xml @@ -43,7 +43,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> - <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="01/1/2018" stepKey="fillFromDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <click selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="expandConditions"/> <!-- Scroll down to fix some flaky behavior... --> <scrollTo selector="{{PriceRuleConditionsSection.conditionsTab}}" stepKey="scrollToConditionsTab"/> From 1f93850a824670a59ebba93a506df777f731c031 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Fri, 12 Oct 2018 11:37:00 -0500 Subject: [PATCH 292/812] MAGETWO-95238: Cannot reset customer password from Admin Panel - fix integration tests --- .../Magento/Customer/Controller/Adminhtml/IndexTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php index 4262967aa8d1a..2fe49efd74a6d 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php @@ -738,7 +738,7 @@ public function testValidateCustomerWithAddressFailure() public function testResetPasswordActionNoCustomerId() { // No customer ID in post, will just get redirected to base - $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setMethod(HttpRequest::METHOD_GET); $this->dispatch('backend/customer/index/resetPassword'); $this->assertRedirect($this->stringStartsWith($this->_baseControllerUrl)); } @@ -749,7 +749,7 @@ public function testResetPasswordActionNoCustomerId() public function testResetPasswordActionBadCustomerId() { // Bad customer ID in post, will just get redirected to base - $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setMethod(HttpRequest::METHOD_GET); $this->getRequest()->setPostValue(['customer_id' => '789']); $this->dispatch('backend/customer/index/resetPassword'); $this->assertRedirect($this->stringStartsWith($this->_baseControllerUrl)); @@ -761,7 +761,7 @@ public function testResetPasswordActionBadCustomerId() public function testResetPasswordActionSuccess() { $this->getRequest()->setPostValue(['customer_id' => '1']); - $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setMethod(HttpRequest::METHOD_GET); $this->dispatch('backend/customer/index/resetPassword'); $this->assertSessionMessages( $this->equalTo(['The customer will receive an email with a link to reset password.']), From cda686799600a3c631822a161eb40ec02a786b87 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Fri, 12 Oct 2018 13:03:40 -0500 Subject: [PATCH 293/812] MAGETWO-90660: Skip Flaky MTF Tests - skip tests --- .../Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml | 1 + .../app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml index 2cb0e2874040b..7c12b546d1359 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml @@ -105,6 +105,7 @@ <data name="issue" xsi:type="string">MAGETWO-66737: Magento\Checkout\Test\TestCase\OnePageCheckoutTest with OnePageCheckoutTestVariation3 and 4 is not stable</data> </variation> <variation name="OnePageCheckoutTestVariation4" summary="One Page Checkout Products with Special Prices" ticketId="MAGETWO-12429"> + <data name="issue" xsi:type="string">MAGETWO-95659: Fix and Unskip MTF OnePageCheckoutOfflinePaymentMethodsTest</data> <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test, severity:S0</data> <data name="products/0" xsi:type="string">catalogProductSimple::product_with_special_price</data> <data name="products/1" xsi:type="string">configurableProduct::product_with_special_price</data> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml index 5c05d4a840009..3480c88d652ee 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml @@ -29,6 +29,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderAddresses" /> </variation> <variation name="OnePageCheckoutUsingNonDefaultAddress" summary="Checkout as Customer using non default address" ticketId="MAGETWO-42602"> + <data name="issue" xsi:type="string">MAGETWO-95660: Fix and Unskip MTF OnePageCheckoutTest</data> <data name="tag" xsi:type="string">severity:S1</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="customer/dataset" xsi:type="string">customer_US_DE_UK</data> From b3d3f2eaa3d6aded859493da10ec274ed40bf388 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 12 Oct 2018 13:19:49 -0500 Subject: [PATCH 294/812] MAGETWO-71675: Customer can't see available Payment Method for specific country --- .../Magento/Checkout/Model/ShippingInformationManagement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php index 6bd78cecd3a6b..cd3bd2c5a7deb 100644 --- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php +++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php @@ -161,7 +161,7 @@ public function saveAddressInformation( $address->setCustomerAddressId(null); } - if (!$billingAddress->getCustomerAddressId()) { + if ($billingAddress && !$billingAddress->getCustomerAddressId()) { $billingAddress->setCustomerAddressId(null); } From e2e3be0f2afda3d04fa355516d50274aaaa5f220 Mon Sep 17 00:00:00 2001 From: avattam <> Date: Fri, 12 Oct 2018 13:50:05 -0500 Subject: [PATCH 295/812] MAGETWO-95111: Creating new storeview validation - added mftf test changes to cover the bug fix --- .../AdminCreateStoreViewActionGroup.xml | 14 ++++++- .../AdminNewStoreViewActionsSection.xml | 1 + .../Mftf/Section/AdminStoresGridSection.xml | 1 - .../Test/AdminCreateStoreViewCodeTest.xml | 39 ------------------- .../Mftf/Test/AdminCreateStoreViewTest.xml | 14 ++++++- 5 files changed, 25 insertions(+), 44 deletions(-) delete mode 100644 app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml index 6ce33f3be3622..934fdf049bc61 100644 --- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml @@ -24,8 +24,18 @@ <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> - <waitForPageLoad stepKey="waitForPageLoad2" /> - <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" stepKey="waitForPageReolad"/> + <waitForElementNotVisible selector="{{AdminNewStoreViewActionsSection.loadingMask}}" stepKey="waitForElementVisible"/> + </actionGroup> + + <actionGroup name="AdminCreateStoreViewActionSaveGroup"> + <waitForLoadingMaskToDisappear stepKey="waitForGridLoad"/> + <waitForElementVisible selector="{{AdminStoresGridSection.websiteFilterTextField}}" stepKey="waitForStoreGridToReload2"/> <see userInput="You saved the store view." stepKey="seeSavedMessage" /> </actionGroup> + + <actionGroup name="AdminCreateStoreViewCodeUniquenessActionGroup"> + <waitForLoadingMaskToDisappear stepKey="waitForForm"/> + <see userInput="Store with the same code already exists." stepKey="seeMessage" /> + </actionGroup> + </actionGroups> diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreViewActionsSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreViewActionsSection.xml index faffc69dc6975..0e3a74fccf9f0 100644 --- a/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreViewActionsSection.xml +++ b/app/code/Magento/Store/Test/Mftf/Section/AdminNewStoreViewActionsSection.xml @@ -11,5 +11,6 @@ <element name="delete" type="button" selector="#delete" timeout="30"/> <element name="resetButton" type="button" selector="#reset" timeout="30"/> <element name="saveButton" type="button" selector="#save" timeout="60"/> + <element name="loadingMask" type="text" selector=".loading-mask"/> </section> </sections> diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml index 6b2c38502923a..04cbeb5bc596e 100644 --- a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml +++ b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml @@ -12,7 +12,6 @@ <element name="createWebsite" type="button" selector="#add"/> </section> <section name="AdminStoresGridSection"> - <element name="loadingMask" type="text" selector=".admin__data-grid-loading-mask[data-component*='notification_area.notification_area.columns']"/> <element name="storeGrpFilterTextField" type="input" selector="#storeGrid_filter_group_title"/> <element name="websiteFilterTextField" type="input" selector="#storeGrid_filter_website_title"/> <element name="storeFilterTextField" type="input" selector="#storeGrid_filter_store_title"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml deleted file mode 100644 index 473b0c1663033..0000000000000 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewCodeTest.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<!-- Test XML Example --> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminCreateStoreViewCodeTest"> - <annotations> - <features value="Store"/> - <stories value="Create a store view new in admin"/> - <title value="Admin should be able to create a store view new"/> - <description value="Admin should be able to create a store view new"/> - <group value="storeViewGroup"/> - <severity value="AVERAGE"/> - </annotations> - <before> - <actionGroup ref="LoginActionGroup" stepKey="login"/> - </before> - <amOnPage url="{{AdminSystemStoreViewPage.url}}" stepKey="navigateToNewStoreView"/> - <waitForPageLoad stepKey="waitForPageLoad1" /> - <!--Create Store View and and check for loading-mask!--> - <fillField selector="{{AdminNewStoreSection.storeNameTextField}}" userInput="{{customStore.name}}" stepKey="enterStoreViewName" /> - <fillField selector="{{AdminNewStoreSection.storeCodeTextField}}" userInput="{{customStore.code}}" stepKey="enterStoreViewCode" /> - <selectOption selector="{{AdminNewStoreSection.statusDropdown}}" userInput="Enabled" stepKey="setStatus" /> - <click selector="{{AdminNewStoreViewActionsSection.saveButton}}" stepKey="clickSaveStoreView" /> - <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> - <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> - <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> - <waitForPageLoad time="60" stepKey="wait1"/> - <waitForElementNotVisible selector="{{AdminStoresGridSection.loadingMask}}" stepKey="waitForLoadingMaskToLoad"/> - <waitForLoadingMaskToDisappear stepKey="waitForGridLoad"/> - <waitForPageLoad time="60" stepKey="wait2"/> - <waitForElementVisible selector="{{AdminStoresGridSection.websiteFilterTextField}}" stepKey="waitForStoreGridToReload2"/> - <see userInput="You saved the store view." stepKey="seeSavedMessage" /> - </test> -</tests> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewTest.xml index 54d392d0c06f1..e7a3d03f337db 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewTest.xml @@ -15,15 +15,25 @@ <description value="Admin should be able to create a store view"/> <group value="storeView"/> <severity value="AVERAGE"/> + <testCaseId value="MAGETWO-95111"/> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="login"/> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView" /> + <!--<createData stepKey="b2" entity="customStoreGroup"/>--> </before> - <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView" /> - <!--Confirm new store view on Store Grid--> + <!--Save store view on Store Grid--> + <actionGroup ref="AdminCreateStoreViewActionSaveGroup" stepKey="createStoreViewSave" /> + <!--Confirm new store view created on Store Grid--> <fillField selector="{{AdminStoresGridSection.storeFilterTextField}}" userInput="{{customStore.name}}" stepKey="fillStoreViewFilter"/> <click selector="{{AdminStoresGridSection.searchButton}}" stepKey="clickSearch" /> <waitForPageLoad stepKey="waitForPageLoad"/> <see selector="{{AdminStoresGridSection.storeNameInFirstRow}}" userInput="{{customStore.name}}" stepKey="seeNewStoreView" /> + <!--Creating the same store view to validate the code uniqueness on store form--> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView2" /> + <actionGroup ref="AdminCreateStoreViewCodeUniquenessActionGroup" stepKey="createStoreViewCode" /> + <after> + <actionGroup ref="logout" stepKey="logout"/> + </after> </test> </tests> From 735a01df04dfbd8fb4f6abd2ba0e83044fa03fcf Mon Sep 17 00:00:00 2001 From: avattam <> Date: Fri, 12 Oct 2018 14:14:42 -0500 Subject: [PATCH 296/812] MAGETWO-95111: Creating new storeview validation - Added fixes to mftf tests --- .../Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml index 934fdf049bc61..6cbbb7ae22014 100644 --- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml @@ -26,16 +26,15 @@ <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> <waitForElementNotVisible selector="{{AdminNewStoreViewActionsSection.loadingMask}}" stepKey="waitForElementVisible"/> </actionGroup> - + <!--Save the Store view--> <actionGroup name="AdminCreateStoreViewActionSaveGroup"> <waitForLoadingMaskToDisappear stepKey="waitForGridLoad"/> <waitForElementVisible selector="{{AdminStoresGridSection.websiteFilterTextField}}" stepKey="waitForStoreGridToReload2"/> <see userInput="You saved the store view." stepKey="seeSavedMessage" /> </actionGroup> - + <!--Save the same Store view code for code validation--> <actionGroup name="AdminCreateStoreViewCodeUniquenessActionGroup"> <waitForLoadingMaskToDisappear stepKey="waitForForm"/> <see userInput="Store with the same code already exists." stepKey="seeMessage" /> </actionGroup> - </actionGroups> From b68802f2a07b342a56a36a74ff7383975f42332c Mon Sep 17 00:00:00 2001 From: pganapat <prabhuramgr28493@gmail.com> Date: Fri, 12 Oct 2018 15:08:56 -0500 Subject: [PATCH 297/812] MAGETWO-95213: Updating Product Status With Mass Action By Scope Updates The Default Value - Modified store_id validation to take in store_id from filters, when store is null in params. --- .../Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php index b7655f7ee2862..83278ca78c738 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php @@ -87,7 +87,7 @@ public function execute() $filterRequest = $this->getRequest()->getParam('filters', null); $status = (int) $this->getRequest()->getParam('status'); - if (null !== $storeId && null !== $filterRequest) { + if (null === $storeId && null !== $filterRequest) { $storeId = (isset($filterRequest['store_id'])) ? (int) $filterRequest['store_id'] : 0; } From 1b56213a6d7e3c2afeb690ac9828f4dc6c0e8336 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Thu, 11 Oct 2018 16:06:29 -0500 Subject: [PATCH 298/812] MAGETWO-95356: Import is successful without notice about category name updates --- .../Import/Product/CategoryProcessor.php | 14 ++---- .../Import/Product/CategoryProcessorTest.php | 48 +++++++++++-------- .../Exception/UrlAlreadyExistsException.php | 6 ++- .../Catalog/_files/category_duplicates.php | 2 +- .../_files/category_duplicates_rollback.php | 34 +++++++++++++ .../Model/Import/ProductTest.php | 17 +------ .../_files/update_category_duplicates.php | 17 +++++++ .../update_category_duplicates_rollback.php | 18 +++++++ 8 files changed, 109 insertions(+), 47 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php create mode 100644 dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php index a5aefff656bd3..951989146e67e 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php @@ -66,6 +66,8 @@ public function __construct( } /** + * Initialize categories + * * @return $this */ protected function initCategories() @@ -104,7 +106,6 @@ protected function initCategories() * * @param string $name * @param int $parentId - * * @return int */ protected function createCategory($name, $parentId) @@ -120,13 +121,8 @@ protected function createCategory($name, $parentId) $category->setIsActive(true); $category->setIncludeInMenu(true); $category->setAttributeSetId($category->getDefaultAttributeSetId()); - try { - $category->save(); - $this->categoriesCache[$category->getId()] = $category; - } catch (\Exception $e) { - $this->addFailedCategory($category, $e); - } - + $category->save(); + $this->categoriesCache[$category->getId()] = $category; return $category->getId(); } @@ -134,7 +130,6 @@ protected function createCategory($name, $parentId) * Returns ID of category by string path creating nonexistent ones. * * @param string $categoryPath - * * @return int */ protected function upsertCategory($categoryPath) @@ -165,7 +160,6 @@ protected function upsertCategory($categoryPath) * * @param string $categoriesString * @param string $categoriesSeparator - * * @return array */ public function upsertCategories($categoriesString, $categoriesSeparator) diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/CategoryProcessorTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/CategoryProcessorTest.php index 69f4a465e3309..919f0cfda7cbe 100644 --- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/CategoryProcessorTest.php +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/CategoryProcessorTest.php @@ -34,41 +34,49 @@ class CategoryProcessorTest extends \PHPUnit\Framework\TestCase */ protected $product; + /** + * @var \Magento\Catalog\Model\Category + */ + private $childCategory; + + /** + * \Magento\Catalog\Model\Category + */ + private $parentCategory; + protected function setUp() { $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->objectManagerHelper = new ObjectManagerHelper($this); - $childCategory = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) + $this->childCategory = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) ->disableOriginalConstructor() ->getMock(); - $childCategory->method('getId')->will($this->returnValue(self::CHILD_CATEGORY_ID)); - $childCategory->method('getName')->will($this->returnValue(self::CHILD_CATEGORY_NAME)); - $childCategory->method('getPath')->will($this->returnValue( + $this->childCategory->method('getId')->will($this->returnValue(self::CHILD_CATEGORY_ID)); + $this->childCategory->method('getName')->will($this->returnValue(self::CHILD_CATEGORY_NAME)); + $this->childCategory->method('getPath')->will($this->returnValue( self::PARENT_CATEGORY_ID . CategoryProcessor::DELIMITER_CATEGORY . self::CHILD_CATEGORY_ID )); - $childCategory->method('save')->willThrowException(new \Exception()); - - $parentCategory = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) + $this->parentCategory = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) ->disableOriginalConstructor() ->getMock(); - $parentCategory->method('getId')->will($this->returnValue(self::PARENT_CATEGORY_ID)); - $parentCategory->method('getName')->will($this->returnValue('Parent')); - $parentCategory->method('getPath')->will($this->returnValue(self::PARENT_CATEGORY_ID)); + $this->parentCategory->method('getId')->will($this->returnValue(self::PARENT_CATEGORY_ID)); + $this->parentCategory->method('getName')->will($this->returnValue('Parent')); + $this->parentCategory->method('getPath')->will($this->returnValue(self::PARENT_CATEGORY_ID)); $categoryCollection = $this->objectManagerHelper->getCollectionMock( \Magento\Catalog\Model\ResourceModel\Category\Collection::class, [ - self::PARENT_CATEGORY_ID => $parentCategory, - self::CHILD_CATEGORY_ID => $childCategory, + self::PARENT_CATEGORY_ID => $this->parentCategory, + self::CHILD_CATEGORY_ID => $this->childCategory, ] ); $map = [ - [self::PARENT_CATEGORY_ID, $parentCategory], - [self::CHILD_CATEGORY_ID, $childCategory], + [self::PARENT_CATEGORY_ID, $this->parentCategory], + [self::CHILD_CATEGORY_ID, $this->childCategory], ]; $categoryCollection->expects($this->any()) ->method('getItemById') @@ -91,7 +99,7 @@ protected function setUp() $categoryFactory = $this->createPartialMock(\Magento\Catalog\Model\CategoryFactory::class, ['create']); - $categoryFactory->method('create')->will($this->returnValue($childCategory)); + $categoryFactory->method('create')->will($this->returnValue($this->childCategory)); $this->categoryProcessor = new \Magento\CatalogImportExport\Model\Import\Product\CategoryProcessor( @@ -110,11 +118,13 @@ public function testUpsertCategories() /** * Tests case when newly created category save throws exception. */ - public function testCreateCategoryException() + public function testUpsertCategoriesWithAlreadyExistsException() { - $method = new \ReflectionMethod(CategoryProcessor::class, 'createCategory'); - $method->setAccessible(true); - $method->invoke($this->categoryProcessor, self::CHILD_CATEGORY_NAME, self::PARENT_CATEGORY_ID); + $exception = new \Magento\Framework\Exception\AlreadyExistsException(); + $categoriesSeparator = '/'; + $categoryName = 'Exception Category'; + $this->childCategory->method('save')->willThrowException($exception); + $this->categoryProcessor->upsertCategories($categoryName, $categoriesSeparator); $this->assertNotEmpty($this->categoryProcessor->getFailedCategories()); } diff --git a/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php b/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php index c7e83819f2569..c7071076bd55a 100644 --- a/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php +++ b/app/code/Magento/UrlRewrite/Model/Exception/UrlAlreadyExistsException.php @@ -8,10 +8,12 @@ use Magento\Framework\Phrase; /** + * Specific exception for URL key already exists + * * @api * @since 100.2.0 */ -class UrlAlreadyExistsException extends \Magento\Framework\Exception\LocalizedException +class UrlAlreadyExistsException extends \Magento\Framework\Exception\AlreadyExistsException { /** * @var array @@ -34,6 +36,8 @@ public function __construct(Phrase $phrase = null, \Exception $cause = null, $co } /** + * Get URLs + * * @return array * @since 100.2.0 */ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates.php index d3825675b7244..46d5bfea6459c 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates.php @@ -15,7 +15,7 @@ )->setParentId( 2 )->setPath( - '1/2' + '1/2/444' )->setLevel( '2' )->setDefaultSortBy( diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php new file mode 100644 index 0000000000000..a1dc418e15633 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Framework\Exception\NoSuchEntityException; + +/** @var \Magento\Framework\ObjectManagerInterface $objectManager */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var \Magento\Framework\Registry $registry */ +$registry = $objectManager->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */ +$categoryCollection = $objectManager->create(\Magento\Catalog\Model\ResourceModel\Category\Collection::class); +$categoryCollection + ->addAttributeToFilter('level', 2) + ->load() + ->delete(); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); +try { + $product = $productRepository->get('simple3', false, null, true); + $productRepository->delete($product); +} catch (NoSuchEntityException $e) { +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index c5e704c2434b5..bbe96d89f5728 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -1292,12 +1292,10 @@ public function categoryTestDataProvider() * @magentoAppArea adminhtml * @magentoDbIsolation disabled * @magentoAppIsolation enabled - * @magentoDataFixture Magento/Catalog/_files/category_duplicates.php + * @magentoDataFixture Magento/CatalogImportExport/_files/update_category_duplicates.php */ public function testProductDuplicateCategories() { - $this->markTestSkipped('Due to MAGETWO-48956'); - $csvFixture = 'products_duplicate_category.csv'; // import data from CSV file $pathToFile = __DIR__ . '/_files/' . $csvFixture; @@ -1322,19 +1320,6 @@ public function testProductDuplicateCategories() $this->assertTrue($errors->getErrorsCount() === 0); - /** @var \Magento\Catalog\Model\Category $category */ - $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\Category::class - ); - - $category->load(444); - - $this->assertTrue($category !== null); - - $category->setName( - 'Category 2-updated' - )->save(); - $this->_model->importData(); $errorProcessor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php new file mode 100644 index 0000000000000..27ca8e7a04413 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php @@ -0,0 +1,17 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require dirname(dirname(__DIR__)) . '/Catalog/_files/category_duplicates.php'; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var \Magento\Catalog\Model\Category $category */ +$categoryModel = $objectManager->create(\Magento\Catalog\Model\Category::class); +$categoryModel->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID); + +$categoryModel->load(444) + ->setName('Category 2-updated') + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php new file mode 100644 index 0000000000000..f3bb3d0415afa --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +require dirname(dirname(__DIR__)) . '/Catalog/_files/category_duplicates_rollback.php'; + +//Delete products created in CSV import +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); +$csvProductSkus = ['simple1', 'simple2', 'simple3']; +foreach($csvProductSkus as $sku) { + try { + $product = $productRepository->get($sku, false, null, true); + $productRepository->delete($product); + } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + } +} From 2d22b204052208e24ec586625397327e1aa08a56 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Thu, 11 Oct 2018 14:54:58 -0500 Subject: [PATCH 299/812] MAGETWO-95259: CatalogSearch module deprecation must be reverted - Removed deprecation of the classes necessary for the work of ElasticSearch (or any other search adapter) --- .../CatalogSearch/Block/Advanced/Result.php | 2 -- .../Adapter/Aggregation/AggregationResolver.php | 5 ++--- .../Aggregation/Checker/Query/CatalogView.php | 4 +--- .../Aggregation/RequestCheckerComposite.php | 5 ++--- .../Aggregation/RequestCheckerInterface.php | 3 --- .../Magento/CatalogSearch/Model/Advanced.php | 2 -- .../Model/Advanced/Request/Builder.php | 6 ++++-- .../Model/Indexer/Fulltext/Action/Full.php | 3 --- .../Indexer/Fulltext/Plugin/Product/Action.php | 2 -- .../Model/Indexer/IndexStructure.php | 16 ++++++---------- .../Model/Indexer/IndexStructureProxy.php | 7 +++---- .../Model/Indexer/IndexSwitcherInterface.php | 5 ++--- .../Model/Indexer/IndexSwitcherProxy.php | 5 +---- .../Model/Indexer/Scope/ScopeProxy.php | 10 ++-------- .../CatalogSearch/Model/Indexer/Scope/State.php | 7 ++++--- .../Model/ResourceModel/Advanced.php | 3 --- .../Model/ResourceModel/Advanced/Collection.php | 8 ++++---- .../Model/ResourceModel/Fulltext.php | 2 -- .../Model/ResourceModel/Fulltext/Collection.php | 1 + .../Model/ResourceModel/Search/Collection.php | 2 -- .../Model/Search/RequestGenerator.php | 4 ++-- .../Search/Adapter/Mysql/ConditionManager.php | 2 +- 22 files changed, 35 insertions(+), 69 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php index 79f6024132be7..7c8e65b249139 100644 --- a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php +++ b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php @@ -18,8 +18,6 @@ * * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Result extends Template { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php index 639c0aecb3615..8a484d4cc7903 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/AggregationResolver.php @@ -15,8 +15,7 @@ use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection as AttributeCollection; /** - * @deprecated - * @see \Magento\ElasticSearch + * Aggregation resolver. */ class AggregationResolver implements AggregationResolverInterface { @@ -79,7 +78,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function resolve(RequestInterface $request, array $documentIds) { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php index 1ac7ad3773740..42da02f8ca4ff 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/CatalogView.php @@ -17,8 +17,6 @@ * Request checker for catalog view. * * Checks catalog view query whether required to collect all attributes for entity. - * @deprecated - * @see \Magento\ElasticSearch */ class CatalogView implements RequestCheckerInterface { @@ -53,7 +51,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function isApplicable(RequestInterface $request) { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php index 7e0ad7c46d6f3..75910e1720734 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerComposite.php @@ -10,8 +10,7 @@ use Magento\Store\Model\StoreManagerInterface; /** - * @deprecated - * @see \Magento\ElasticSearch + * Composite request checker. */ class RequestCheckerComposite implements RequestCheckerInterface { @@ -57,7 +56,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function isApplicable(RequestInterface $request) { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php index 81b7414380bf1..7efe708a5755f 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/RequestCheckerInterface.php @@ -9,9 +9,6 @@ /** * RequestCheckerInterface provides the interface to work with query checkers. - * - * @deprecated - * @see \Magento\ElasticSearch */ interface RequestCheckerInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Advanced.php b/app/code/Magento/CatalogSearch/Model/Advanced.php index b49809cfc8059..28f67a7829e7e 100644 --- a/app/code/Magento/CatalogSearch/Model/Advanced.php +++ b/app/code/Magento/CatalogSearch/Model/Advanced.php @@ -43,8 +43,6 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Advanced extends \Magento\Framework\Model\AbstractModel { diff --git a/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php b/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php index be2609ccc338a..9e7737123b2ec 100644 --- a/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php +++ b/app/code/Magento/CatalogSearch/Model/Advanced/Request/Builder.php @@ -8,14 +8,16 @@ use Magento\Framework\Search\Request\Builder as RequestBuilder; /** + * Catalog search advanced request builder. + * * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Builder extends RequestBuilder { /** + * Bind value to query. + * * @param string $attributeCode * @param array|string $attributeValue * @return void diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php index 9ea4007c6bde1..8a18c1bfcc576 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php @@ -22,9 +22,6 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * - * @deprecated - * @see \Magento\ElasticSearch */ class Full { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product/Action.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product/Action.php index 2ead0ac0ac612..75bf4cbd0f3f6 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product/Action.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product/Action.php @@ -24,8 +24,6 @@ class Action extends AbstractIndexerPlugin * @return ProductAction * * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * @deprecated - * @see ElasticSearch module is default search engine starting from 2.3. CatalogSearch would be removed in 2.4 */ public function afterUpdateAttributes( ProductAction $subject, diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php index 0308fda657375..0d226acdc3d7b 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php @@ -15,10 +15,10 @@ use Magento\Framework\Search\Request\IndexScopeResolverInterface; /** + * Catalog search index structure. + * * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class IndexStructure implements IndexStructureInterface { @@ -45,9 +45,7 @@ public function __construct( } /** - * @param string $index - * @param Dimension[] $dimensions - * @return void + * @inheritdoc */ public function delete($index, array $dimensions = []) { @@ -58,11 +56,7 @@ public function delete($index, array $dimensions = []) } /** - * @param string $index - * @param array $fields - * @param array $dimensions - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * @return void + * @inheritdoc */ public function create($index, array $fields, array $dimensions = []) { @@ -70,6 +64,8 @@ public function create($index, array $fields, array $dimensions = []) } /** + * Create fulltext index table. + * * @param string $tableName * @throws \Zend_Db_Exception * @return void diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php index f8863aca8db9c..c62d2a033565f 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureProxy.php @@ -8,8 +8,7 @@ use Magento\Framework\Indexer\IndexStructureInterface; /** - * @deprecated - * @see \Magento\ElasticSearch + * Catalog search index structure proxy. */ class IndexStructureProxy implements IndexStructureInterface { @@ -33,7 +32,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function delete( $index, @@ -43,7 +42,7 @@ public function delete( } /** - * {@inheritdoc} + * @inheritdoc */ public function create( $index, diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php index 1cdd9c5b9fa5e..f45ef11a86389 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php @@ -6,11 +6,10 @@ namespace Magento\CatalogSearch\Model\Indexer; /** - * Provides a functionality to replace main index with its temporary representation + * Provides a functionality to replace main index with its temporary representation. + * * @api * @since 100.2.0 - * @deprecated - * @see \Magento\ElasticSearch */ interface IndexSwitcherInterface { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php index cd0aa12f9137b..e4a20cc188fbd 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php @@ -11,9 +11,6 @@ /** * Proxy for adapter-specific index switcher - * - * @deprecated - * @see \Magento\ElasticSearch */ class IndexSwitcherProxy implements IndexSwitcherInterface { @@ -54,7 +51,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritDoc * * As index switcher is an optional part of the search SPI, it may be not defined by a search engine. * It is especially reasonable for search engines with pre-defined indexes declaration (like Sphinx) diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php index 02d533d7bcb49..fcecb36e7d508 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php @@ -9,11 +9,7 @@ use Magento\Framework\Search\Request\Dimension; /** - * Implementation of IndexScopeResolverInterface which resolves index scope dynamically - * depending on current scope state - * - * @deprecated - * @see \Magento\ElasticSearch + * Implementation of IndexScopeResolverInterface which resolves index scope dynamically depending on current scope state */ class ScopeProxy implements \Magento\Framework\Search\Request\IndexScopeResolverInterface { @@ -67,9 +63,7 @@ private function create($state) } /** - * @param string $index - * @param Dimension[] $dimensions - * @return string + * @inheritdoc */ public function resolve($index, array $dimensions) { diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php index 35f616f109638..a12ae8e69c310 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php @@ -18,9 +18,6 @@ * The 'use_temporary_table' state is an opposite for 'use_main_table' * which means that default indexer table should be left unchanged during indexation * and temporary table should be used instead. - * - * @deprecated - * @see \Magento\ElasticSearch */ class State { @@ -34,6 +31,7 @@ class State /** * Set the state to use temporary Index + * * @return void */ public function useTemporaryIndex() @@ -43,6 +41,7 @@ public function useTemporaryIndex() /** * Set the state to use regular Index + * * @return void */ public function useRegularIndex() @@ -51,6 +50,8 @@ public function useRegularIndex() } /** + * Get state. + * * @return string */ public function getState() diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php index d88e5627df0e0..05254a50aadc6 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced.php @@ -8,11 +8,8 @@ /** * Advanced Catalog Search resource model * - * @author Magento Core Team <core@magentocommerce.com> * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Advanced extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php index a660cf62b1ad9..948ae70793c6f 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php @@ -17,14 +17,13 @@ use Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitationFactory; /** - * Collection Advanced + * Advanced search collection + * + * This collection should be refactored to not have dependencies on MySQL-specific implementation. * - * @author Magento Core Team <core@magentocommerce.com> * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection { @@ -41,6 +40,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection /** * @var \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory + * @deprecated There must be no dependencies on specific adapter in generic search implementation */ private $temporaryStorageFactory; diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php index ff9aeb4fb4474..0835fb66f876a 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext.php @@ -14,8 +14,6 @@ * * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Fulltext extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index 79d03b6fad2ca..81121b9d21e12 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -72,6 +72,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection /** * @var \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory + * @deprecated There must be no dependencies on specific adapter in generic search implementation */ private $temporaryStorageFactory; diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php index aff558c6d0244..b958de91314f4 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php @@ -12,8 +12,6 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection implements \Magento\Search\Model\SearchCollectionInterface diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php index 6e6aee08f926e..0adc2fcecbfa7 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php @@ -14,10 +14,10 @@ use Magento\Framework\Search\Request\QueryInterface; /** + * Catalog search request generator. + * * @api * @since 100.0.2 - * @deprecated - * @see \Magento\ElasticSearch */ class RequestGenerator { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php index 413af71814198..e56559563c35a 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ConditionManager.php @@ -34,7 +34,7 @@ public function __construct(ResourceConnection $resource) } /** - * Wrap query with parentheces. + * Wrap query with parentheses. * * @param string $query * @return string From cf28335ad72a3fdc86193b25b23bad993e2a01dd Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Fri, 12 Oct 2018 16:11:01 -0500 Subject: [PATCH 300/812] MAGETWO-90660: Skip Flaky MTF Tests - remove second issue node --- .../app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml index 3480c88d652ee..5c05d4a840009 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml @@ -29,7 +29,6 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderAddresses" /> </variation> <variation name="OnePageCheckoutUsingNonDefaultAddress" summary="Checkout as Customer using non default address" ticketId="MAGETWO-42602"> - <data name="issue" xsi:type="string">MAGETWO-95660: Fix and Unskip MTF OnePageCheckoutTest</data> <data name="tag" xsi:type="string">severity:S1</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="customer/dataset" xsi:type="string">customer_US_DE_UK</data> From 4e382cc735a883c9dcd8eaeeedc185d7faa06a7f Mon Sep 17 00:00:00 2001 From: hiren pandya <infinitehdp@gmail.com> Date: Sat, 13 Oct 2018 11:52:27 +0530 Subject: [PATCH 301/812] Special price date from issue resolve --- .../Controller/Adminhtml/Product/Initialization/Helper.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index d82f4a04fb252..e14916f731ed8 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -463,6 +463,7 @@ private function fillProductOptions(Product $product, array $productOptions) private function convertSpecialFromDateStringToObject($productData) { if (isset($productData['special_from_date']) && $productData['special_from_date'] != '') { + $productData['special_from_date'] = $this->dateFilter->filter($productData['special_from_date']); $productData['special_from_date'] = new \DateTime($productData['special_from_date']); } From fd8a5a90b32431fbdd275000624723b106c81841 Mon Sep 17 00:00:00 2001 From: hiren pandya <hiren.pandya@krishtechnolabs.com> Date: Sat, 13 Oct 2018 13:00:58 +0530 Subject: [PATCH 302/812] Revert "Special price date from issue resolve" This reverts commit 4e382cc735a883c9dcd8eaeeedc185d7faa06a7f. --- .../Controller/Adminhtml/Product/Initialization/Helper.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index e14916f731ed8..d82f4a04fb252 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -463,7 +463,6 @@ private function fillProductOptions(Product $product, array $productOptions) private function convertSpecialFromDateStringToObject($productData) { if (isset($productData['special_from_date']) && $productData['special_from_date'] != '') { - $productData['special_from_date'] = $this->dateFilter->filter($productData['special_from_date']); $productData['special_from_date'] = new \DateTime($productData['special_from_date']); } From 88592facd5d34872ac2f2051dda246703091cacc Mon Sep 17 00:00:00 2001 From: hiren pandya <hiren.pandya@krishtechnolabs.com> Date: Sat, 13 Oct 2018 13:03:07 +0530 Subject: [PATCH 303/812] Special price date from issue resolve --- .../Controller/Adminhtml/Product/Initialization/Helper.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index d82f4a04fb252..8999b03b647a3 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -463,6 +463,7 @@ private function fillProductOptions(Product $product, array $productOptions) private function convertSpecialFromDateStringToObject($productData) { if (isset($productData['special_from_date']) && $productData['special_from_date'] != '') { + $productData['special_from_date'] = $this->dateFilter->filter($productData['special_from_date']); $productData['special_from_date'] = new \DateTime($productData['special_from_date']); } From 96507df2629a67616931f8aa404b5b2cf6f5440a Mon Sep 17 00:00:00 2001 From: Luuk Schakenraad <luuk@chessweb.eu> Date: Sat, 13 Oct 2018 13:56:47 +0200 Subject: [PATCH 304/812] Fix disappearing navigation arrows in fotorama zoom --- lib/web/fotorama/fotorama.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/fotorama/fotorama.js b/lib/web/fotorama/fotorama.js index a16e437c0d7ff..9f756696008cc 100644 --- a/lib/web/fotorama/fotorama.js +++ b/lib/web/fotorama/fotorama.js @@ -2098,7 +2098,7 @@ fotoramaVersion = '4.6.4'; o_navTop = opts.navposition === 'top'; classes.remove.push(selectClass); - $arrs.toggle(opts.arrows); + $arrs.toggle(!!opts.arrows); } else { o_nav = false; $arrs.hide(); From f5b496c2a033b48e8669db81b421f16240c359d0 Mon Sep 17 00:00:00 2001 From: Arnoud Beekman <arnoud.beekman@mediact.nl> Date: Sat, 13 Oct 2018 15:05:44 +0200 Subject: [PATCH 305/812] Use the correct method to validate if attribute is required --- app/code/Magento/Eav/Model/Attribute/Data/Text.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Attribute/Data/Text.php b/app/code/Magento/Eav/Model/Attribute/Data/Text.php index a26a92df385f2..a919a54cf6289 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/Text.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/Text.php @@ -67,7 +67,7 @@ public function validateValue($value) $value = $this->getEntity()->getDataUsingMethod($attribute->getAttributeCode()); } - if (!$attribute->isRequired() && empty($value)) { + if (!$attribute->getIsRequired() && empty($value)) { return true; } From ad85c9546bd06adddd908aef9cc0bb3b2346463e Mon Sep 17 00:00:00 2001 From: Matei Purcaru <matei.purcaru@gmail.com> Date: Sun, 14 Oct 2018 17:59:50 +0300 Subject: [PATCH 306/812] magento/graphql-ce#41: [Query] My Account > My Orders --- .../SalesGraphQl/Model/Resolver/Orders.php | 87 +++++++++++++ app/code/Magento/SalesGraphQl/README.md | 6 + app/code/Magento/SalesGraphQl/composer.json | 27 ++++ app/code/Magento/SalesGraphQl/etc/module.xml | 10 ++ .../Magento/SalesGraphQl/etc/schema.graphqls | 19 +++ .../Magento/SalesGraphQl/registration.php | 10 ++ dev/tests/api-functional/phpunit.xml.dist | 56 +++++++++ .../Magento/GraphQl/Sales/OrdersTest.php | 115 ++++++++++++++++++ .../Sales/_files/order_list_rollback.php | 2 - .../Sales/_files/orders_with_customer.php | 101 +++++++++++++++ .../_files/orders_with_customer_rollback.php | 7 ++ 11 files changed, 438 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php create mode 100644 app/code/Magento/SalesGraphQl/README.md create mode 100644 app/code/Magento/SalesGraphQl/composer.json create mode 100644 app/code/Magento/SalesGraphQl/etc/module.xml create mode 100644 app/code/Magento/SalesGraphQl/etc/schema.graphqls create mode 100644 app/code/Magento/SalesGraphQl/registration.php create mode 100644 dev/tests/api-functional/phpunit.xml.dist create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php new file mode 100644 index 0000000000000..c6c6ac6203789 --- /dev/null +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\SalesGraphQl\Model\Resolver; + +use Magento\Authorization\Model\UserContextInterface; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Sales\Model\ResourceModel\Order\CollectionFactoryInterface; +use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccountInterface; + +/** + * {@inheritdoc} + */ +class Orders implements ResolverInterface +{ + /** + * @var UserContextInterface + */ + private $userContext; + + /** + * @var CollectionFactoryInterface + */ + private $collectionFactory; + + /** + * @var CheckCustomerAccountInterface + */ + private $checkCustomerAccount; + + /** + * Orders constructor. + * @param UserContextInterface $userContext + * @param CollectionFactoryInterface $collectionFactory + */ + public function __construct( + UserContextInterface $userContext, + CollectionFactoryInterface $collectionFactory, + CheckCustomerAccountInterface $checkCustomerAccount + ) { + $this->userContext = $userContext; + $this->collectionFactory = $collectionFactory; + $this->checkCustomerAccount = $checkCustomerAccount; + + } + + /** + * {@inheritdoc} + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + + $customerId = $this->userContext->getUserId(); + + $this->checkCustomerAccount->execute($customerId, $this->userContext->getUserType()); + + $orders = $this->collectionFactory->create($customerId); + $items = []; + + // @TODO Add shipping & billing address in response + // @TODO Add order currency object in response + /** @var \Magento\Sales\Model\Order $order */ + foreach ($orders as $order) { + $items[] = [ + 'id' => $order->getId(), + 'increment_id' => $order->getIncrementId(), + 'created_at' => $order->getCreatedAt(), + 'grant_total' => $order->getGrandTotal(), + 'state' => $order->getState(), + 'status' => $order->getStatus() + ]; + } + + return ['items' => $items]; + } +} \ No newline at end of file diff --git a/app/code/Magento/SalesGraphQl/README.md b/app/code/Magento/SalesGraphQl/README.md new file mode 100644 index 0000000000000..d827613570bad --- /dev/null +++ b/app/code/Magento/SalesGraphQl/README.md @@ -0,0 +1,6 @@ +# SalesGraphQl + +**SalesGraphQl** provides type and resolver information for the GraphQl module +to generate sales orders information endpoints. + +Also will provides endpoints for modifying an order. diff --git a/app/code/Magento/SalesGraphQl/composer.json b/app/code/Magento/SalesGraphQl/composer.json new file mode 100644 index 0000000000000..b75e18c7b7a97 --- /dev/null +++ b/app/code/Magento/SalesGraphQl/composer.json @@ -0,0 +1,27 @@ +{ + "name": "magento/module-sales-graph-ql", + "description": "N/A", + "type": "magento2-module", + "require": { + "php": "~7.1.3||~7.2.0", + "magento/framework": "*", + "magento/module-customer": "*", + "magento/module-catalog": "*", + "magento/module-store": "*" + }, + "suggest": { + "magento/module-graph-ql": "*" + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\SalesGraphQl\\": "" + } + } +} diff --git a/app/code/Magento/SalesGraphQl/etc/module.xml b/app/code/Magento/SalesGraphQl/etc/module.xml new file mode 100644 index 0000000000000..70a55db67a506 --- /dev/null +++ b/app/code/Magento/SalesGraphQl/etc/module.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:Module/etc/module.xsd"> + <module name="Magento_SalesGraphQl"/> +</config> diff --git a/app/code/Magento/SalesGraphQl/etc/schema.graphqls b/app/code/Magento/SalesGraphQl/etc/schema.graphqls new file mode 100644 index 0000000000000..c137484cd2f65 --- /dev/null +++ b/app/code/Magento/SalesGraphQl/etc/schema.graphqls @@ -0,0 +1,19 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +type Query { + customerOrders: Orders @resolver(class: "Magento\\SalesGraphQl\\Model\\Resolver\\Orders") @doc(description: "List of customer orders") +} + +type Order @doc(description: "Order mapping fields") { + id: Int + increment_id: String + created_at: String + grant_total: Float + state: String + status: String +} + +type Orders { + items: [Order] @doc(description: "Array of orders") +} diff --git a/app/code/Magento/SalesGraphQl/registration.php b/app/code/Magento/SalesGraphQl/registration.php new file mode 100644 index 0000000000000..afb4091bfa32f --- /dev/null +++ b/app/code/Magento/SalesGraphQl/registration.php @@ -0,0 +1,10 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\Component\ComponentRegistrar; + +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_SalesGraphQl', __DIR__); diff --git a/dev/tests/api-functional/phpunit.xml.dist b/dev/tests/api-functional/phpunit.xml.dist new file mode 100644 index 0000000000000..c869608462d08 --- /dev/null +++ b/dev/tests/api-functional/phpunit.xml.dist @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * PHPUnit configuration for GraphQL web API functional tests. + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.2/phpunit.xsd" + colors="true" + columns="max" + beStrictAboutTestsThatDoNotTestAnything="false" + bootstrap="./framework/bootstrap.php" +> + <!-- Test suites definition --> + <testsuites> + <testsuite name="Magento GraphQL web API functional tests"> + <directory suffix="Test.php">testsuite/Magento/GraphQl</directory> + </testsuite> + </testsuites> + + <!-- PHP INI settings and constants definition --> + <php> + <includePath>./testsuite</includePath> + <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/> + <const name="TESTS_GLOBAL_CONFIG_FILE" value="config/config-global.php"/> + <!-- Webserver URL --> + <const name="TESTS_BASE_URL" value="http://magento.inno"/> + <!-- Webserver API user --> + <const name="TESTS_WEBSERVICE_USER" value="admin"/> + <!-- Webserver API key --> + <const name="TESTS_WEBSERVICE_APIKEY" value="123123q"/> + <!-- Define if debugger should be started using XDEBUG_SESSION cookie --> + <const name="TESTS_XDEBUG_ENABLED" value="true"/> + <!-- Define XDEBUG_SESSION cookie value--> + <const name="TESTS_XDEBUG_SESSION" value="MEETMAGENTO" /> + + <ini name="date.timezone" value="America/Los_Angeles"/> + + <!-- Semicolon-separated 'glob' patterns, that match global XML configuration files --> + <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> + <!-- Whether to cleanup the application before running tests or not --> + <const name="TESTS_CLEANUP" value="enabled"/> + <!--Defines if Magento should be installed before tests execution--> + <const name="TESTS_MAGENTO_INSTALLATION" value="disabled"/> + <!-- Magento mode for tests execution. Possible values are "default", "developer" and "production". --> + <const name="TESTS_MAGENTO_MODE" value="default"/> + </php> + + <!-- Test listeners --> + <listeners> + <listener class="Magento\TestFramework\Event\PhpUnit"/> + </listeners> +</phpunit> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php new file mode 100644 index 0000000000000..3a85c044f16a9 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php @@ -0,0 +1,115 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Sales; + +use Magento\Integration\Api\CustomerTokenServiceInterface; +use Magento\TestFramework\TestCase\GraphQlAbstract; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Class OrdersTest + */ +class OrdersTest extends GraphQlAbstract +{ + /** + * @var CustomerTokenServiceInterface + */ + private $customerTokenService; + + /** + * {@inheritdoc} + */ + protected function setUp() + { + parent::setUp(); + $objectManager = Bootstrap::getObjectManager(); + $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Sales/_files/orders_with_customer.php + */ + public function testOrdersQuery() + { + $query = + <<<QUERY +query { + customerOrders { + items { + id + increment_id + created_at + grant_total + state + status + } + } +} +QUERY; + + $currentEmail = 'customer@example.com'; + $currentPassword = 'password'; + + $response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword)); + + $expectedData = [ + [ + 'increment_id' => '100000002', + 'state' => \Magento\Sales\Model\Order::STATE_NEW, + 'status' => 'processing', + 'grant_total' => 120.00 + ], + [ + 'increment_id' => '100000003', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'processing', + 'grant_total' => 130.00 + ], + [ + 'increment_id' => '100000004', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'closed', + 'grant_total' => 140.00 + ], + [ + 'increment_id' => '100000005', + 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, + 'status' => 'complete', + 'grant_total' => 150.00 + ], + [ + 'increment_id' => '100000006', + 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, + 'status' => 'complete', + 'grant_total' => 160.00 + ] + ]; + + $actualData = $response['customerOrders']['items']; + + foreach ($expectedData as $key => $data) { + $this->assertEquals($data['increment_id'], $actualData[$key]['increment_id']); + $this->assertEquals($data['grant_total'], $actualData[$key]['grant_total']); + $this->assertEquals($data['state'], $actualData[$key]['state']); + $this->assertEquals($data['status'], $actualData[$key]['status']); + } + } + + /** + * @param string $email + * @param string $password + * @return array + * @throws \Magento\Framework\Exception\AuthenticationException + */ + private function getCustomerAuthHeaders(string $email, string $password): array + { + $customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password); + return ['Authorization' => 'Bearer ' . $customerToken]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_rollback.php index aae4a557ba1ed..6e24cee501f51 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_rollback.php @@ -4,6 +4,4 @@ * See COPYING.txt for license details. */ -use Magento\Sales\Model\Order; - require 'default_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php new file mode 100644 index 0000000000000..e649396391ca9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Sales\Model\Order; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Model\Order\Address as OrderAddress; + +require 'order.php'; +/** @var Order $order */ +/** @var Order\Payment $payment */ +/** @var Order\Item $orderItem */ +/** @var array $addressData Data for creating addresses for the orders. */ +$orders = [ + [ + 'increment_id' => '100000002', + 'state' => \Magento\Sales\Model\Order::STATE_NEW, + 'status' => 'processing', + 'grand_total' => 120.00, + 'subtotal' => 120.00, + 'base_grand_total' => 120.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000003', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'processing', + 'grand_total' => 130.00, + 'base_grand_total' => 130.00, + 'subtotal' => 130.00, + 'store_id' => 0, + 'website_id' => 0, + 'payment' => $payment + ], + [ + 'increment_id' => '100000004', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'closed', + 'grand_total' => 140.00, + 'base_grand_total' => 140.00, + 'subtotal' => 140.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000005', + 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, + 'status' => 'complete', + 'grand_total' => 150.00, + 'base_grand_total' => 150.00, + 'subtotal' => 150.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000006', + 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, + 'status' => 'complete', + 'grand_total' => 160.00, + 'base_grand_total' => 160.00, + 'subtotal' => 160.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], +]; + +/** @var OrderRepositoryInterface $orderRepository */ +$orderRepository = $objectManager->create(OrderRepositoryInterface::class); +/** @var array $orderData */ +foreach ($orders as $orderData) { + /** @var $order \Magento\Sales\Model\Order */ + $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\Order::class + ); + + // Reset addresses + /** @var Order\Address $billingAddress */ + $billingAddress = $objectManager->create(OrderAddress::class, ['data' => $addressData]); + $billingAddress->setAddressType('billing'); + + $shippingAddress = clone $billingAddress; + $shippingAddress->setId(null)->setAddressType('shipping'); + + $order + ->setData($orderData) + ->addItem($orderItem) + ->setCustomerIsGuest(false) + ->setCustomerId(1) + ->setCustomerEmail('customer@example.com') + ->setBillingAddress($billingAddress) + ->setShippingAddress($shippingAddress); + + $orderRepository->save($order); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php new file mode 100644 index 0000000000000..6e24cee501f51 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php @@ -0,0 +1,7 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'default_rollback.php'; From 623a6b01330545582c3337813d803691faefef87 Mon Sep 17 00:00:00 2001 From: Luuk Schakenraad <luuk@chessweb.eu> Date: Sun, 14 Oct 2018 19:25:42 +0200 Subject: [PATCH 307/812] Fix disappearing navigation arrows in fotorama zoom also in fotorama.min.js --- lib/web/fotorama/fotorama.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/fotorama/fotorama.min.js b/lib/web/fotorama/fotorama.min.js index 9842f20cdc2af..0a0cbd9db7e74 100644 --- a/lib/web/fotorama/fotorama.min.js +++ b/lib/web/fotorama/fotorama.min.js @@ -1 +1 @@ -fotoramaVersion="4.6.4";(function(window,document,location,$,undefined){"use strict";var _fotoramaClass="fotorama",_fullscreenClass="fotorama__fullscreen",wrapClass=_fotoramaClass+"__wrap",wrapCss2Class=wrapClass+"--css2",wrapCss3Class=wrapClass+"--css3",wrapVideoClass=wrapClass+"--video",wrapFadeClass=wrapClass+"--fade",wrapSlideClass=wrapClass+"--slide",wrapNoControlsClass=wrapClass+"--no-controls",wrapNoShadowsClass=wrapClass+"--no-shadows",wrapPanYClass=wrapClass+"--pan-y",wrapRtlClass=wrapClass+"--rtl",wrapOnlyActiveClass=wrapClass+"--only-active",wrapNoCaptionsClass=wrapClass+"--no-captions",wrapToggleArrowsClass=wrapClass+"--toggle-arrows",stageClass=_fotoramaClass+"__stage",stageFrameClass=stageClass+"__frame",stageFrameVideoClass=stageFrameClass+"--video",stageShaftClass=stageClass+"__shaft",grabClass=_fotoramaClass+"__grab",pointerClass=_fotoramaClass+"__pointer",arrClass=_fotoramaClass+"__arr",arrDisabledClass=arrClass+"--disabled",arrPrevClass=arrClass+"--prev",arrNextClass=arrClass+"--next",navClass=_fotoramaClass+"__nav",navWrapClass=navClass+"-wrap",navShaftClass=navClass+"__shaft",navShaftVerticalClass=navWrapClass+"--vertical",navShaftListClass=navWrapClass+"--list",navShafthorizontalClass=navWrapClass+"--horizontal",navDotsClass=navClass+"--dots",navThumbsClass=navClass+"--thumbs",navFrameClass=navClass+"__frame",fadeClass=_fotoramaClass+"__fade",fadeFrontClass=fadeClass+"-front",fadeRearClass=fadeClass+"-rear",shadowClass=_fotoramaClass+"__shadow",shadowsClass=shadowClass+"s",shadowsLeftClass=shadowsClass+"--left",shadowsRightClass=shadowsClass+"--right",shadowsTopClass=shadowsClass+"--top",shadowsBottomClass=shadowsClass+"--bottom",activeClass=_fotoramaClass+"__active",selectClass=_fotoramaClass+"__select",hiddenClass=_fotoramaClass+"--hidden",fullscreenClass=_fotoramaClass+"--fullscreen",fullscreenIconClass=_fotoramaClass+"__fullscreen-icon",errorClass=_fotoramaClass+"__error",loadingClass=_fotoramaClass+"__loading",loadedClass=_fotoramaClass+"__loaded",loadedFullClass=loadedClass+"--full",loadedImgClass=loadedClass+"--img",grabbingClass=_fotoramaClass+"__grabbing",imgClass=_fotoramaClass+"__img",imgFullClass=imgClass+"--full",thumbClass=_fotoramaClass+"__thumb",thumbArrLeft=thumbClass+"__arr--left",thumbArrRight=thumbClass+"__arr--right",thumbBorderClass=thumbClass+"-border",htmlClass=_fotoramaClass+"__html",videoContainerClass=_fotoramaClass+"-video-container",videoClass=_fotoramaClass+"__video",videoPlayClass=videoClass+"-play",videoCloseClass=videoClass+"-close",horizontalImageClass=_fotoramaClass+"_horizontal_ratio",verticalImageClass=_fotoramaClass+"_vertical_ratio",fotoramaSpinnerClass=_fotoramaClass+"__spinner",spinnerShowClass=fotoramaSpinnerClass+"--show";var JQUERY_VERSION=$&&$.fn.jquery.split(".");if(!JQUERY_VERSION||JQUERY_VERSION[0]<1||JQUERY_VERSION[0]==1&&JQUERY_VERSION[1]<8){throw"Fotorama requires jQuery 1.8 or later and will not run without it."}var _={};var Modernizr=function(window,document,undefined){var version="2.8.3",Modernizr={},docElement=document.documentElement,mod="modernizr",modElem=document.createElement(mod),mStyle=modElem.style,inputElem,toString={}.toString,prefixes=" -webkit- -moz- -o- -ms- ".split(" "),omPrefixes="Webkit Moz O ms",cssomPrefixes=omPrefixes.split(" "),domPrefixes=omPrefixes.toLowerCase().split(" "),tests={},inputs={},attrs={},classes=[],slice=classes.slice,featureName,injectElementWithStyles=function(rule,callback,nodes,testnames){var style,ret,node,docOverflow,div=document.createElement("div"),body=document.body,fakeBody=body||document.createElement("body");if(parseInt(nodes,10)){while(nodes--){node=document.createElement("div");node.id=testnames?testnames[nodes]:mod+(nodes+1);div.appendChild(node)}}style=["­",'<style id="s',mod,'">',rule,"</style>"].join("");div.id=mod;(body?div:fakeBody).innerHTML+=style;fakeBody.appendChild(div);if(!body){fakeBody.style.background="";fakeBody.style.overflow="hidden";docOverflow=docElement.style.overflow;docElement.style.overflow="hidden";docElement.appendChild(fakeBody)}ret=callback(div,rule);if(!body){fakeBody.parentNode.removeChild(fakeBody);docElement.style.overflow=docOverflow}else{div.parentNode.removeChild(div)}return!!ret},_hasOwnProperty={}.hasOwnProperty,hasOwnProp;if(!is(_hasOwnProperty,"undefined")&&!is(_hasOwnProperty.call,"undefined")){hasOwnProp=function(object,property){return _hasOwnProperty.call(object,property)}}else{hasOwnProp=function(object,property){return property in object&&is(object.constructor.prototype[property],"undefined")}}if(!Function.prototype.bind){Function.prototype.bind=function bind(that){var target=this;if(typeof target!="function"){throw new TypeError}var args=slice.call(arguments,1),bound=function(){if(this instanceof bound){var F=function(){};F.prototype=target.prototype;var self=new F;var result=target.apply(self,args.concat(slice.call(arguments)));if(Object(result)===result){return result}return self}else{return target.apply(that,args.concat(slice.call(arguments)))}};return bound}}function setCss(str){mStyle.cssText=str}function setCssAll(str1,str2){return setCss(prefixes.join(str1+";")+(str2||""))}function is(obj,type){return typeof obj===type}function contains(str,substr){return!!~(""+str).indexOf(substr)}function testProps(props,prefixed){for(var i in props){var prop=props[i];if(!contains(prop,"-")&&mStyle[prop]!==undefined){return prefixed=="pfx"?prop:true}}return false}function testDOMProps(props,obj,elem){for(var i in props){var item=obj[props[i]];if(item!==undefined){if(elem===false)return props[i];if(is(item,"function")){return item.bind(elem||obj)}return item}}return false}function testPropsAll(prop,prefixed,elem){var ucProp=prop.charAt(0).toUpperCase()+prop.slice(1),props=(prop+" "+cssomPrefixes.join(ucProp+" ")+ucProp).split(" ");if(is(prefixed,"string")||is(prefixed,"undefined")){return testProps(props,prefixed)}else{props=(prop+" "+domPrefixes.join(ucProp+" ")+ucProp).split(" ");return testDOMProps(props,prefixed,elem)}}tests["touch"]=function(){var bool;if("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch){bool=true}else{injectElementWithStyles(["@media (",prefixes.join("touch-enabled),("),mod,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(node){bool=node.offsetTop===9})}return bool};tests["csstransforms3d"]=function(){var ret=!!testPropsAll("perspective");if(ret&&"webkitPerspective"in docElement.style){injectElementWithStyles("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(node,rule){ret=node.offsetLeft===9&&node.offsetHeight===3})}return ret};tests["csstransitions"]=function(){return testPropsAll("transition")};for(var feature in tests){if(hasOwnProp(tests,feature)){featureName=feature.toLowerCase();Modernizr[featureName]=tests[feature]();classes.push((Modernizr[featureName]?"":"no-")+featureName)}}Modernizr.addTest=function(feature,test){if(typeof feature=="object"){for(var key in feature){if(hasOwnProp(feature,key)){Modernizr.addTest(key,feature[key])}}}else{feature=feature.toLowerCase();if(Modernizr[feature]!==undefined){return Modernizr}test=typeof test=="function"?test():test;if(typeof enableClasses!=="undefined"&&enableClasses){docElement.className+=" "+(test?"":"no-")+feature}Modernizr[feature]=test}return Modernizr};setCss("");modElem=inputElem=null;Modernizr._version=version;Modernizr._prefixes=prefixes;Modernizr._domPrefixes=domPrefixes;Modernizr._cssomPrefixes=cssomPrefixes;Modernizr.testProp=function(prop){return testProps([prop])};Modernizr.testAllProps=testPropsAll;Modernizr.testStyles=injectElementWithStyles;Modernizr.prefixed=function(prop,obj,elem){if(!obj){return testPropsAll(prop,"pfx")}else{return testPropsAll(prop,obj,elem)}};return Modernizr}(window,document);var fullScreenApi={ok:false,is:function(){return false},request:function(){},cancel:function(){},event:"",prefix:""},browserPrefixes="webkit moz o ms khtml".split(" ");if(typeof document.cancelFullScreen!="undefined"){fullScreenApi.ok=true}else{for(var i=0,il=browserPrefixes.length;i<il;i++){fullScreenApi.prefix=browserPrefixes[i];if(typeof document[fullScreenApi.prefix+"CancelFullScreen"]!="undefined"){fullScreenApi.ok=true;break}}}if(fullScreenApi.ok){fullScreenApi.event=fullScreenApi.prefix+"fullscreenchange";fullScreenApi.is=function(){switch(this.prefix){case"":return document.fullScreen;case"webkit":return document.webkitIsFullScreen;default:return document[this.prefix+"FullScreen"]}};fullScreenApi.request=function(el){return this.prefix===""?el.requestFullScreen():el[this.prefix+"RequestFullScreen"]()};fullScreenApi.cancel=function(el){return this.prefix===""?document.cancelFullScreen():document[this.prefix+"CancelFullScreen"]()}}function bez(coOrdArray){var encodedFuncName="bez_"+$.makeArray(arguments).join("_").replace(".","p");if(typeof $["easing"][encodedFuncName]!=="function"){var polyBez=function(p1,p2){var A=[null,null],B=[null,null],C=[null,null],bezCoOrd=function(t,ax){C[ax]=3*p1[ax];B[ax]=3*(p2[ax]-p1[ax])-C[ax];A[ax]=1-C[ax]-B[ax];return t*(C[ax]+t*(B[ax]+t*A[ax]))},xDeriv=function(t){return C[0]+t*(2*B[0]+3*A[0]*t)},xForT=function(t){var x=t,i=0,z;while(++i<14){z=bezCoOrd(x,0)-t;if(Math.abs(z)<.001)break;x-=z/xDeriv(x)}return x};return function(t){return bezCoOrd(xForT(t),1)}};$["easing"][encodedFuncName]=function(x,t,b,c,d){return c*polyBez([coOrdArray[0],coOrdArray[1]],[coOrdArray[2],coOrdArray[3]])(t/d)+b}}return encodedFuncName}var $WINDOW=$(window),$DOCUMENT=$(document),$HTML,$BODY,QUIRKS_FORCE=location.hash.replace("#","")==="quirks",TRANSFORMS3D=Modernizr.csstransforms3d,CSS3=TRANSFORMS3D&&!QUIRKS_FORCE,COMPAT=TRANSFORMS3D||document.compatMode==="CSS1Compat",FULLSCREEN=fullScreenApi.ok,MOBILE=navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i),SLOW=!CSS3||MOBILE,MS_POINTER=navigator.msPointerEnabled,WHEEL="onwheel"in document.createElement("div")?"wheel":document.onmousewheel!==undefined?"mousewheel":"DOMMouseScroll",TOUCH_TIMEOUT=250,TRANSITION_DURATION=300,SCROLL_LOCK_TIMEOUT=1400,AUTOPLAY_INTERVAL=5e3,MARGIN=2,THUMB_SIZE=64,WIDTH=500,HEIGHT=333,STAGE_FRAME_KEY="$stageFrame",NAV_DOT_FRAME_KEY="$navDotFrame",NAV_THUMB_FRAME_KEY="$navThumbFrame",AUTO="auto",BEZIER=bez([.1,0,.25,1]),MAX_WIDTH=1200,thumbsPerSlide=1,OPTIONS={width:null,minwidth:null,maxwidth:"100%",height:null,minheight:null,maxheight:null,ratio:null,margin:MARGIN,nav:"dots",navposition:"bottom",navwidth:null,thumbwidth:THUMB_SIZE,thumbheight:THUMB_SIZE,thumbmargin:MARGIN,thumbborderwidth:MARGIN,allowfullscreen:false,transition:"slide",clicktransition:null,transitionduration:TRANSITION_DURATION,captions:true,startindex:0,loop:false,autoplay:false,stopautoplayontouch:true,keyboard:false,arrows:true,click:true,swipe:false,trackpad:false,shuffle:false,direction:"ltr",shadows:true,showcaption:true,navdir:"horizontal",navarrows:true,navtype:"thumbs"},KEYBOARD_OPTIONS={left:true,right:true,down:true,up:true,space:false,home:false,end:false};function noop(){}function minMaxLimit(value,min,max){return Math.max(isNaN(min)?-Infinity:min,Math.min(isNaN(max)?Infinity:max,value))}function readTransform(css,dir){return css.match(/ma/)&&css.match(/-?\d+(?!d)/g)[css.match(/3d/)?dir==="vertical"?13:12:dir==="vertical"?5:4]}function readPosition($el,dir){if(CSS3){return+readTransform($el.css("transform"),dir)}else{return+$el.css(dir==="vertical"?"top":"left").replace("px","")}}function getTranslate(pos,direction){var obj={};if(CSS3){switch(direction){case"vertical":obj.transform="translate3d(0, "+pos+"px,0)";break;case"list":break;default:obj.transform="translate3d("+pos+"px,0,0)";break}}else{direction==="vertical"?obj.top=pos:obj.left=pos}return obj}function getDuration(time){return{"transition-duration":time+"ms"}}function unlessNaN(value,alternative){return isNaN(value)?alternative:value}function numberFromMeasure(value,measure){return unlessNaN(+String(value).replace(measure||"px",""))}function numberFromPercent(value){return/%$/.test(value)?numberFromMeasure(value,"%"):undefined}function numberFromWhatever(value,whole){return unlessNaN(numberFromPercent(value)/100*whole,numberFromMeasure(value))}function measureIsValid(value){return(!isNaN(numberFromMeasure(value))||!isNaN(numberFromMeasure(value,"%")))&&value}function getPosByIndex(index,side,margin,baseIndex){return(index-(baseIndex||0))*(side+(margin||0))}function getIndexByPos(pos,side,margin,baseIndex){return-Math.round(pos/(side+(margin||0))-(baseIndex||0))}function bindTransitionEnd($el){var elData=$el.data();if(elData.tEnd)return;var el=$el[0],transitionEndEvent={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",msTransition:"MSTransitionEnd",transition:"transitionend"};addEvent(el,transitionEndEvent[Modernizr.prefixed("transition")],function(e){elData.tProp&&e.propertyName.match(elData.tProp)&&elData.onEndFn()});elData.tEnd=true}function afterTransition($el,property,fn,time){var ok,elData=$el.data();if(elData){elData.onEndFn=function(){if(ok)return;ok=true;clearTimeout(elData.tT);fn()};elData.tProp=property;clearTimeout(elData.tT);elData.tT=setTimeout(function(){elData.onEndFn()},time*1.5);bindTransitionEnd($el)}}function stop($el,pos){var dir=$el.navdir||"horizontal";if($el.length){var elData=$el.data();if(CSS3){$el.css(getDuration(0));elData.onEndFn=noop;clearTimeout(elData.tT)}else{$el.stop()}var lockedPos=getNumber(pos,function(){return readPosition($el,dir)});$el.css(getTranslate(lockedPos,dir));return lockedPos}}function getNumber(){var number;for(var _i=0,_l=arguments.length;_i<_l;_i++){number=_i?arguments[_i]():arguments[_i];if(typeof number==="number"){break}}return number}function edgeResistance(pos,edge){return Math.round(pos+(edge-pos)/1.5)}function getProtocol(){getProtocol.p=getProtocol.p||(location.protocol==="https:"?"https://":"http://");return getProtocol.p}function parseHref(href){var a=document.createElement("a");a.href=href;return a}function findVideoId(href,forceVideo){if(typeof href!=="string")return href;href=parseHref(href);var id,type;if(href.host.match(/youtube\.com/)&&href.search){id=href.search.split("v=")[1];if(id){var ampersandPosition=id.indexOf("&");if(ampersandPosition!==-1){id=id.substring(0,ampersandPosition)}type="youtube"}}else if(href.host.match(/youtube\.com|youtu\.be/)){id=href.pathname.replace(/^\/(embed\/|v\/)?/,"").replace(/\/.*/,"");type="youtube"}else if(href.host.match(/vimeo\.com/)){type="vimeo";id=href.pathname.replace(/^\/(video\/)?/,"").replace(/\/.*/,"")}if((!id||!type)&&forceVideo){id=href.href;type="custom"}return id?{id:id,type:type,s:href.search.replace(/^\?/,""),p:getProtocol()}:false}function getVideoThumbs(dataFrame,data,fotorama){var img,thumb,video=dataFrame.video;if(video.type==="youtube"){thumb=getProtocol()+"img.youtube.com/vi/"+video.id+"/default.jpg";img=thumb.replace(/\/default.jpg$/,"/hqdefault.jpg");dataFrame.thumbsReady=true}else if(video.type==="vimeo"){$.ajax({url:getProtocol()+"vimeo.com/api/v2/video/"+video.id+".json",dataType:"jsonp",success:function(json){dataFrame.thumbsReady=true;updateData(data,{img:json[0].thumbnail_large,thumb:json[0].thumbnail_small},dataFrame.i,fotorama)}})}else{dataFrame.thumbsReady=true}return{img:img,thumb:thumb}}function updateData(data,_dataFrame,i,fotorama){for(var _i=0,_l=data.length;_i<_l;_i++){var dataFrame=data[_i];if(dataFrame.i===i&&dataFrame.thumbsReady){var clear={videoReady:true};clear[STAGE_FRAME_KEY]=clear[NAV_THUMB_FRAME_KEY]=clear[NAV_DOT_FRAME_KEY]=false;fotorama.splice(_i,1,$.extend({},dataFrame,clear,_dataFrame));break}}}function getDataFromHtml($el){var data=[];function getDataFromImg($img,imgData,checkVideo){var $child=$img.children("img").eq(0),_imgHref=$img.attr("href"),_imgSrc=$img.attr("src"),_thumbSrc=$child.attr("src"),_video=imgData.video,video=checkVideo?findVideoId(_imgHref,_video===true):false;if(video){_imgHref=false}else{video=_video}getDimensions($img,$child,$.extend(imgData,{video:video,img:imgData.img||_imgHref||_imgSrc||_thumbSrc,thumb:imgData.thumb||_thumbSrc||_imgSrc||_imgHref}))}function getDimensions($img,$child,imgData){var separateThumbFLAG=imgData.thumb&&imgData.img!==imgData.thumb,width=numberFromMeasure(imgData.width||$img.attr("width")),height=numberFromMeasure(imgData.height||$img.attr("height"));$.extend(imgData,{width:width,height:height,thumbratio:getRatio(imgData.thumbratio||numberFromMeasure(imgData.thumbwidth||$child&&$child.attr("width")||separateThumbFLAG||width)/numberFromMeasure(imgData.thumbheight||$child&&$child.attr("height")||separateThumbFLAG||height))})}$el.children().each(function(){var $this=$(this),dataFrame=optionsToLowerCase($.extend($this.data(),{id:$this.attr("id")}));if($this.is("a, img")){getDataFromImg($this,dataFrame,true)}else if(!$this.is(":empty")){getDimensions($this,null,$.extend(dataFrame,{html:this,_html:$this.html()}))}else return;data.push(dataFrame)});return data}function isHidden(el){return el.offsetWidth===0&&el.offsetHeight===0}function isDetached(el){return!$.contains(document.documentElement,el)}function waitFor(test,fn,timeout,i){if(!waitFor.i){waitFor.i=1;waitFor.ii=[true]}i=i||waitFor.i;if(typeof waitFor.ii[i]==="undefined"){waitFor.ii[i]=true}if(test()){fn()}else{waitFor.ii[i]&&setTimeout(function(){waitFor.ii[i]&&waitFor(test,fn,timeout,i)},timeout||100)}return waitFor.i++}waitFor.stop=function(i){waitFor.ii[i]=false};function fit($el,measuresToFit){var elData=$el.data(),measures=elData.measures;if(measures&&(!elData.l||elData.l.W!==measures.width||elData.l.H!==measures.height||elData.l.r!==measures.ratio||elData.l.w!==measuresToFit.w||elData.l.h!==measuresToFit.h)){var height=minMaxLimit(measuresToFit.h,0,measures.height),width=height*measures.ratio;UTIL.setRatio($el,width,height);elData.l={W:measures.width,H:measures.height,r:measures.ratio,w:measuresToFit.w,h:measuresToFit.h}}return true}function setStyle($el,style){var el=$el[0];if(el.styleSheet){el.styleSheet.cssText=style}else{$el.html(style)}}function findShadowEdge(pos,min,max,dir){return min===max?false:dir==="vertical"?pos<=min?"top":pos>=max?"bottom":"top bottom":pos<=min?"left":pos>=max?"right":"left right"}function smartClick($el,fn,_options){_options=_options||{};$el.each(function(){var $this=$(this),thisData=$this.data(),startEvent;if(thisData.clickOn)return;thisData.clickOn=true;$.extend(touch($this,{onStart:function(e){startEvent=e;(_options.onStart||noop).call(this,e)},onMove:_options.onMove||noop,onTouchEnd:_options.onTouchEnd||noop,onEnd:function(result){if(result.moved)return;fn.call(this,startEvent)}}),{noMove:true})})}function div(classes,child){return'<div class="'+classes+'">'+(child||"")+"</div>"}function cls(className){return"."+className}function createVideoFrame(videoItem){var frame='<iframe src="'+videoItem.p+videoItem.type+".com/embed/"+videoItem.id+'" frameborder="0" allowfullscreen></iframe>';return frame}function shuffle(array){var l=array.length;while(l){var i=Math.floor(Math.random()*l--);var t=array[l];array[l]=array[i];array[i]=t}return array}function clone(array){return Object.prototype.toString.call(array)=="[object Array]"&&$.map(array,function(frame){return $.extend({},frame)})}function lockScroll($el,left,top){$el.scrollLeft(left||0).scrollTop(top||0)}function optionsToLowerCase(options){if(options){var opts={};$.each(options,function(key,value){opts[key.toLowerCase()]=value});return opts}}function getRatio(_ratio){if(!_ratio)return;var ratio=+_ratio;if(!isNaN(ratio)){return ratio}else{ratio=_ratio.split("/");return+ratio[0]/+ratio[1]||undefined}}function addEvent(el,e,fn,bool){if(!e)return;el.addEventListener?el.addEventListener(e,fn,!!bool):el.attachEvent("on"+e,fn)}function validateRestrictions(position,restriction){if(position>restriction.max){position=restriction.max}else{if(position<restriction.min){position=restriction.min}}return position}function validateSlidePos(opt,navShaftTouchTail,guessIndex,offsetNav,$guessNavFrame,$navWrap,dir){var position,size,wrapSize;if(dir==="horizontal"){size=opt.thumbwidth;wrapSize=$navWrap.width()}else{size=opt.thumbheight;wrapSize=$navWrap.height()}if((size+opt.margin)*(guessIndex+1)>=wrapSize-offsetNav){if(dir==="horizontal"){position=-$guessNavFrame.position().left}else{position=-$guessNavFrame.position().top}}else{if((size+opt.margin)*guessIndex<=Math.abs(offsetNav)){if(dir==="horizontal"){position=-$guessNavFrame.position().left+wrapSize-(size+opt.margin)}else{position=-$guessNavFrame.position().top+wrapSize-(size+opt.margin)}}else{position=offsetNav}}position=validateRestrictions(position,navShaftTouchTail);return position||0}function elIsDisabled(el){return!!el.getAttribute("disabled")}function disableAttr(FLAG,disable){if(disable){return{disabled:FLAG}}else{return{tabindex:FLAG*-1+"",disabled:FLAG}}}function addEnterUp(el,fn){addEvent(el,"keyup",function(e){elIsDisabled(el)||e.keyCode==13&&fn.call(el,e)})}function addFocus(el,fn){addEvent(el,"focus",el.onfocusin=function(e){fn.call(el,e)},true)}function stopEvent(e,stopPropagation){e.preventDefault?e.preventDefault():e.returnValue=false;stopPropagation&&e.stopPropagation&&e.stopPropagation()}function stubEvent($el,eventType){var isIOS=/ip(ad|hone|od)/i.test(window.navigator.userAgent);if(isIOS&&eventType==="touchend"){$el.on("touchend",function(e){$DOCUMENT.trigger("mouseup",e)})}$el.on(eventType,function(e){stopEvent(e,true);return false})}function getDirectionSign(forward){return forward?">":"<"}var UTIL=function(){function setRatioClass($el,wh,ht){var rateImg=wh/ht;if(rateImg<=1){$el.parent().removeClass(horizontalImageClass);$el.parent().addClass(verticalImageClass)}else{$el.parent().removeClass(verticalImageClass);$el.parent().addClass(horizontalImageClass)}}function setThumbAttr($frame,value,searchAttr){var attr=searchAttr;if(!$frame.attr(attr)&&$frame.attr(attr)!==undefined){$frame.attr(attr,value)}if($frame.find("["+attr+"]").length){$frame.find("["+attr+"]").each(function(){$(this).attr(attr,value)})}}function isExpectedCaption(frameItem,isExpected,undefined){var expected=false,frameExpected;frameItem.showCaption===undefined||frameItem.showCaption===true?frameExpected=true:frameExpected=false;if(!isExpected){return false}if(frameItem.caption&&frameExpected){expected=true}return expected}return{setRatio:setRatioClass,setThumbAttr:setThumbAttr,isExpectedCaption:isExpectedCaption}}(UTIL||{},jQuery);function slide($el,options){var elData=$el.data(),elPos=Math.round(options.pos),onEndFn=function(){if(elData&&elData.sliding){elData.sliding=false}(options.onEnd||noop)()};if(typeof options.overPos!=="undefined"&&options.overPos!==options.pos){elPos=options.overPos}var translate=$.extend(getTranslate(elPos,options.direction),options.width&&{width:options.width},options.height&&{height:options.height});if(elData&&elData.sliding){elData.sliding=true}if(CSS3){$el.css($.extend(getDuration(options.time),translate));if(options.time>10){afterTransition($el,"transform",onEndFn,options.time)}else{onEndFn()}}else{$el.stop().animate(translate,options.time,BEZIER,onEndFn)}}function fade($el1,$el2,$frames,options,fadeStack,chain){var chainedFLAG=typeof chain!=="undefined";if(!chainedFLAG){fadeStack.push(arguments);Array.prototype.push.call(arguments,fadeStack.length);if(fadeStack.length>1)return}$el1=$el1||$($el1);$el2=$el2||$($el2);var _$el1=$el1[0],_$el2=$el2[0],crossfadeFLAG=options.method==="crossfade",onEndFn=function(){if(!onEndFn.done){onEndFn.done=true;var args=(chainedFLAG||fadeStack.shift())&&fadeStack.shift();args&&fade.apply(this,args);(options.onEnd||noop)(!!args)}},time=options.time/(chain||1);$frames.removeClass(fadeRearClass+" "+fadeFrontClass);$el1.stop().addClass(fadeRearClass);$el2.stop().addClass(fadeFrontClass);crossfadeFLAG&&_$el2&&$el1.fadeTo(0,0);$el1.fadeTo(crossfadeFLAG?time:0,1,crossfadeFLAG&&onEndFn);$el2.fadeTo(time,0,onEndFn);_$el1&&crossfadeFLAG||_$el2||onEndFn()}var lastEvent,moveEventType,preventEvent,preventEventTimeout,dragDomEl;function extendEvent(e){var touch=(e.touches||[])[0]||e;e._x=touch.pageX||touch.originalEvent.pageX;e._y=touch.clientY||touch.originalEvent.clientY;e._now=$.now()}function touch($el,options){var el=$el[0],tail={},touchEnabledFLAG,startEvent,$target,controlTouch,touchFLAG,targetIsSelectFLAG,targetIsLinkFlag,tolerance,moved;function onStart(e){$target=$(e.target);tail.checked=targetIsSelectFLAG=targetIsLinkFlag=moved=false;if(touchEnabledFLAG||tail.flow||e.touches&&e.touches.length>1||e.which>1||lastEvent&&lastEvent.type!==e.type&&preventEvent||(targetIsSelectFLAG=options.select&&$target.is(options.select,el)))return targetIsSelectFLAG;touchFLAG=e.type==="touchstart";targetIsLinkFlag=$target.is("a, a *",el);controlTouch=tail.control;tolerance=tail.noMove||tail.noSwipe||controlTouch?16:!tail.snap?4:0;extendEvent(e);startEvent=lastEvent=e;moveEventType=e.type.replace(/down|start/,"move").replace(/Down/,"Move");(options.onStart||noop).call(el,e,{control:controlTouch,$target:$target});touchEnabledFLAG=tail.flow=true;if(!touchFLAG||tail.go)stopEvent(e)}function onMove(e){if(e.touches&&e.touches.length>1||MS_POINTER&&!e.isPrimary||moveEventType!==e.type||!touchEnabledFLAG){touchEnabledFLAG&&onEnd();(options.onTouchEnd||noop)();return}extendEvent(e);var xDiff=Math.abs(e._x-startEvent._x),yDiff=Math.abs(e._y-startEvent._y),xyDiff=xDiff-yDiff,xWin=(tail.go||tail.x||xyDiff>=0)&&!tail.noSwipe,yWin=xyDiff<0;if(touchFLAG&&!tail.checked){if(touchEnabledFLAG=xWin){stopEvent(e)}}else{stopEvent(e);if(movedEnough(xDiff,yDiff)){(options.onMove||noop).call(el,e,{touch:touchFLAG})}}if(!moved&&movedEnough(xDiff,yDiff)&&Math.sqrt(Math.pow(xDiff,2)+Math.pow(yDiff,2))>tolerance){moved=true}tail.checked=tail.checked||xWin||yWin}function movedEnough(xDiff,yDiff){return xDiff>yDiff&&xDiff>1.5}function onEnd(e){(options.onTouchEnd||noop)();var _touchEnabledFLAG=touchEnabledFLAG;tail.control=touchEnabledFLAG=false;if(_touchEnabledFLAG){tail.flow=false}if(!_touchEnabledFLAG||targetIsLinkFlag&&!tail.checked)return;e&&stopEvent(e);preventEvent=true;clearTimeout(preventEventTimeout);preventEventTimeout=setTimeout(function(){preventEvent=false},1e3);(options.onEnd||noop).call(el,{moved:moved,$target:$target,control:controlTouch,touch:touchFLAG,startEvent:startEvent,aborted:!e||e.type==="MSPointerCancel"})}function onOtherStart(){if(tail.flow)return;tail.flow=true}function onOtherEnd(){if(!tail.flow)return;tail.flow=false}if(MS_POINTER){addEvent(el,"MSPointerDown",onStart);addEvent(document,"MSPointerMove",onMove);addEvent(document,"MSPointerCancel",onEnd);addEvent(document,"MSPointerUp",onEnd)}else{addEvent(el,"touchstart",onStart);addEvent(el,"touchmove",onMove);addEvent(el,"touchend",onEnd);addEvent(document,"touchstart",onOtherStart);addEvent(document,"touchend",onOtherEnd);addEvent(document,"touchcancel",onOtherEnd);$WINDOW.on("scroll",onOtherEnd);$el.on("mousedown pointerdown",onStart);$DOCUMENT.on("mousemove pointermove",onMove).on("mouseup pointerup",onEnd)}if(Modernizr.touch){dragDomEl="a"}else{dragDomEl="div"}$el.on("click",dragDomEl,function(e){tail.checked&&stopEvent(e)});return tail}function moveOnTouch($el,options){var el=$el[0],elData=$el.data(),tail={},startCoo,coo,startElPos,moveElPos,edge,moveTrack,startTime,endTime,min,max,snap,dir,slowFLAG,controlFLAG,moved,tracked;function startTracking(e,noStop){tracked=true;startCoo=coo=dir==="vertical"?e._y:e._x;startTime=e._now;moveTrack=[[startTime,startCoo]];startElPos=moveElPos=tail.noMove||noStop?0:stop($el,(options.getPos||noop)());(options.onStart||noop).call(el,e)}function onStart(e,result){min=tail.min;max=tail.max;snap=tail.snap,dir=tail.direction||"horizontal",$el.navdir=dir;slowFLAG=e.altKey;tracked=moved=false;controlFLAG=result.control;if(!controlFLAG&&!elData.sliding){startTracking(e)}}function onMove(e,result){if(!tail.noSwipe){if(!tracked){startTracking(e)}coo=dir==="vertical"?e._y:e._x;moveTrack.push([e._now,coo]);moveElPos=startElPos-(startCoo-coo);edge=findShadowEdge(moveElPos,min,max,dir);if(moveElPos<=min){moveElPos=edgeResistance(moveElPos,min)}else if(moveElPos>=max){moveElPos=edgeResistance(moveElPos,max)}if(!tail.noMove){$el.css(getTranslate(moveElPos,dir));if(!moved){moved=true;result.touch||MS_POINTER||$el.addClass(grabbingClass)}(options.onMove||noop).call(el,e,{pos:moveElPos,edge:edge})}}}function onEnd(result){if(tail.noSwipe&&result.moved)return;if(!tracked){startTracking(result.startEvent,true)}result.touch||MS_POINTER||$el.removeClass(grabbingClass);endTime=$.now();var _backTimeIdeal=endTime-TOUCH_TIMEOUT,_backTime,_timeDiff,_timeDiffLast,backTime=null,backCoo,virtualPos,limitPos,newPos,overPos,time=TRANSITION_DURATION,speed,friction=options.friction;for(var _i=moveTrack.length-1;_i>=0;_i--){_backTime=moveTrack[_i][0];_timeDiff=Math.abs(_backTime-_backTimeIdeal);if(backTime===null||_timeDiff<_timeDiffLast){backTime=_backTime;backCoo=moveTrack[_i][1]}else if(backTime===_backTimeIdeal||_timeDiff>_timeDiffLast){break}_timeDiffLast=_timeDiff}newPos=minMaxLimit(moveElPos,min,max);var cooDiff=backCoo-coo,forwardFLAG=cooDiff>=0,timeDiff=endTime-backTime,longTouchFLAG=timeDiff>TOUCH_TIMEOUT,swipeFLAG=!longTouchFLAG&&moveElPos!==startElPos&&newPos===moveElPos;if(snap){newPos=minMaxLimit(Math[swipeFLAG?forwardFLAG?"floor":"ceil":"round"](moveElPos/snap)*snap,min,max);min=max=newPos}if(swipeFLAG&&(snap||newPos===moveElPos)){speed=-(cooDiff/timeDiff);time*=minMaxLimit(Math.abs(speed),options.timeLow,options.timeHigh);virtualPos=Math.round(moveElPos+speed*time/friction);if(!snap){newPos=virtualPos}if(!forwardFLAG&&virtualPos>max||forwardFLAG&&virtualPos<min){limitPos=forwardFLAG?min:max;overPos=virtualPos-limitPos;if(!snap){newPos=limitPos}overPos=minMaxLimit(newPos+overPos*.03,limitPos-50,limitPos+50);time=Math.abs((moveElPos-overPos)/(speed/friction))}}time*=slowFLAG?10:1;(options.onEnd||noop).call(el,$.extend(result,{moved:result.moved||longTouchFLAG&&snap,pos:moveElPos,newPos:newPos,overPos:overPos,time:time,dir:dir}))}tail=$.extend(touch(options.$wrap,$.extend({},options,{onStart:onStart,onMove:onMove,onEnd:onEnd})),tail);return tail}function wheel($el,options){var el=$el[0],lockFLAG,lastDirection,lastNow,tail={prevent:{}};addEvent(el,WHEEL,function(e){var yDelta=e.wheelDeltaY||-1*e.deltaY||0,xDelta=e.wheelDeltaX||-1*e.deltaX||0,xWin=Math.abs(xDelta)&&!Math.abs(yDelta),direction=getDirectionSign(xDelta<0),sameDirection=lastDirection===direction,now=$.now(),tooFast=now-lastNow<TOUCH_TIMEOUT;lastDirection=direction;lastNow=now;if(!xWin||!tail.ok||tail.prevent[direction]&&!lockFLAG){return}else{stopEvent(e,true);if(lockFLAG&&sameDirection&&tooFast){return}}if(options.shift){lockFLAG=true;clearTimeout(tail.t);tail.t=setTimeout(function(){lockFLAG=false},SCROLL_LOCK_TIMEOUT)}(options.onEnd||noop)(e,options.shift?direction:xDelta)});return tail}jQuery.Fotorama=function($fotorama,opts){$HTML=$("html");$BODY=$("body");var that=this,stamp=$.now(),stampClass=_fotoramaClass+stamp,fotorama=$fotorama[0],data,dataFrameCount=1,fotoramaData=$fotorama.data(),size,$style=$("<style></style>"),$anchor=$(div(hiddenClass)),$wrap=$fotorama.find(cls(wrapClass)),$stage=$wrap.find(cls(stageClass)),stage=$stage[0],$stageShaft=$fotorama.find(cls(stageShaftClass)),$stageFrame=$(),$arrPrev=$fotorama.find(cls(arrPrevClass)),$arrNext=$fotorama.find(cls(arrNextClass)),$arrs=$fotorama.find(cls(arrClass)),$navWrap=$fotorama.find(cls(navWrapClass)),$nav=$navWrap.find(cls(navClass)),$navShaft=$nav.find(cls(navShaftClass)),$navFrame,$navDotFrame=$(),$navThumbFrame=$(),stageShaftData=$stageShaft.data(),navShaftData=$navShaft.data(),$thumbBorder=$fotorama.find(cls(thumbBorderClass)),$thumbArrLeft=$fotorama.find(cls(thumbArrLeft)),$thumbArrRight=$fotorama.find(cls(thumbArrRight)),$fullscreenIcon=$fotorama.find(cls(fullscreenIconClass)),fullscreenIcon=$fullscreenIcon[0],$videoPlay=$(div(videoPlayClass)),$videoClose=$fotorama.find(cls(videoCloseClass)),videoClose=$videoClose[0],$spinner=$fotorama.find(cls(fotoramaSpinnerClass)),$videoPlaying,activeIndex=false,activeFrame,activeIndexes,repositionIndex,dirtyIndex,lastActiveIndex,prevIndex,nextIndex,nextAutoplayIndex,startIndex,o_loop,o_nav,o_navThumbs,o_navTop,o_allowFullScreen,o_nativeFullScreen,o_fade,o_thumbSide,o_thumbSide2,o_transitionDuration,o_transition,o_shadows,o_rtl,o_keyboard,lastOptions={},measures={},measuresSetFLAG,stageShaftTouchTail={},stageWheelTail={},navShaftTouchTail={},navWheelTail={},scrollTop,scrollLeft,showedFLAG,pausedAutoplayFLAG,stoppedAutoplayFLAG,toDeactivate={},toDetach={},measuresStash,touchedFLAG,hoverFLAG,navFrameKey,stageLeft=0,fadeStack=[];$wrap[STAGE_FRAME_KEY]=$('<div class="'+stageFrameClass+'"></div>');$wrap[NAV_THUMB_FRAME_KEY]=$($.Fotorama.jst.thumb());$wrap[NAV_DOT_FRAME_KEY]=$($.Fotorama.jst.dots());toDeactivate[STAGE_FRAME_KEY]=[];toDeactivate[NAV_THUMB_FRAME_KEY]=[];toDeactivate[NAV_DOT_FRAME_KEY]=[];toDetach[STAGE_FRAME_KEY]={};$wrap.addClass(CSS3?wrapCss3Class:wrapCss2Class);fotoramaData.fotorama=this;function checkForVideo(){$.each(data,function(i,dataFrame){if(!dataFrame.i){dataFrame.i=dataFrameCount++;var video=findVideoId(dataFrame.video,true);if(video){var thumbs={};dataFrame.video=video;if(!dataFrame.img&&!dataFrame.thumb){thumbs=getVideoThumbs(dataFrame,data,that)}else{dataFrame.thumbsReady=true}updateData(data,{img:thumbs.img,thumb:thumbs.thumb},dataFrame.i,that)}}})}function allowKey(key){return o_keyboard[key]}function setStagePosition(){if($stage!==undefined){if(opts.navdir=="vertical"){var padding=opts.thumbwidth+opts.thumbmargin;$stage.css("left",padding);$arrNext.css("right",padding);$fullscreenIcon.css("right",padding);$wrap.css("width",$wrap.css("width")+padding);$stageShaft.css("max-width",$wrap.width()-padding)}else{$stage.css("left","");$arrNext.css("right","");$fullscreenIcon.css("right","");$wrap.css("width",$wrap.css("width")+padding);$stageShaft.css("max-width","")}}}function bindGlobalEvents(FLAG){var keydownCommon="keydown."+_fotoramaClass,localStamp=_fotoramaClass+stamp,keydownLocal="keydown."+localStamp,keyupLocal="keyup."+localStamp,resizeLocal="resize."+localStamp+" "+"orientationchange."+localStamp,showParams;if(FLAG){$DOCUMENT.on(keydownLocal,function(e){var catched,index;if($videoPlaying&&e.keyCode===27){catched=true;unloadVideo($videoPlaying,true,true)}else if(that.fullScreen||opts.keyboard&&!that.index){if(e.keyCode===27){catched=true;that.cancelFullScreen()}else if(e.shiftKey&&e.keyCode===32&&allowKey("space")||!e.altKey&&!e.metaKey&&e.keyCode===37&&allowKey("left")||e.keyCode===38&&allowKey("up")&&$(":focus").attr("data-gallery-role")){that.longPress.progress();index="<"}else if(e.keyCode===32&&allowKey("space")||!e.altKey&&!e.metaKey&&e.keyCode===39&&allowKey("right")||e.keyCode===40&&allowKey("down")&&$(":focus").attr("data-gallery-role")){that.longPress.progress();index=">"}else if(e.keyCode===36&&allowKey("home")){that.longPress.progress();index="<<"}else if(e.keyCode===35&&allowKey("end")){that.longPress.progress();index=">>"}}(catched||index)&&stopEvent(e);showParams={index:index,slow:e.altKey,user:true};index&&(that.longPress.inProgress?that.showWhileLongPress(showParams):that.show(showParams))});if(FLAG){$DOCUMENT.on(keyupLocal,function(e){if(that.longPress.inProgress){that.showEndLongPress({user:true})}that.longPress.reset()})}if(!that.index){$DOCUMENT.off(keydownCommon).on(keydownCommon,"textarea, input, select",function(e){!$BODY.hasClass(_fullscreenClass)&&e.stopPropagation()})}$WINDOW.on(resizeLocal,that.resize)}else{$DOCUMENT.off(keydownLocal);$WINDOW.off(resizeLocal)}}function appendElements(FLAG){if(FLAG===appendElements.f)return;if(FLAG){$fotorama.addClass(_fotoramaClass+" "+stampClass).before($anchor).before($style);addInstance(that)}else{$anchor.detach();$style.detach();$fotorama.html(fotoramaData.urtext).removeClass(stampClass);hideInstance(that)}bindGlobalEvents(FLAG);appendElements.f=FLAG}function setData(){data=that.data=data||clone(opts.data)||getDataFromHtml($fotorama);size=that.size=data.length;ready.ok&&opts.shuffle&&shuffle(data);checkForVideo();activeIndex=limitIndex(activeIndex);size&&appendElements(true)}function stageNoMove(){var _noMove=size<2||$videoPlaying;stageShaftTouchTail.noMove=_noMove||o_fade;stageShaftTouchTail.noSwipe=_noMove||!opts.swipe;!o_transition&&$stageShaft.toggleClass(grabClass,!opts.click&&!stageShaftTouchTail.noMove&&!stageShaftTouchTail.noSwipe);MS_POINTER&&$wrap.toggleClass(wrapPanYClass,!stageShaftTouchTail.noSwipe)}function setAutoplayInterval(interval){if(interval===true)interval="";opts.autoplay=Math.max(+interval||AUTOPLAY_INTERVAL,o_transitionDuration*1.5)}function updateThumbArrow(opt){if(opt.navarrows&&opt.nav==="thumbs"){$thumbArrLeft.show();$thumbArrRight.show()}else{$thumbArrLeft.hide();$thumbArrRight.hide()}}function getThumbsInSlide($el,opts){return Math.floor($wrap.width()/(opts.thumbwidth+opts.thumbmargin))}function setOptions(){if(!opts.nav||opts.nav==="dots"){opts.navdir="horizontal"}that.options=opts=optionsToLowerCase(opts);thumbsPerSlide=getThumbsInSlide($wrap,opts);o_fade=opts.transition==="crossfade"||opts.transition==="dissolve";o_loop=opts.loop&&(size>2||o_fade&&(!o_transition||o_transition!=="slide"));o_transitionDuration=+opts.transitionduration||TRANSITION_DURATION;o_rtl=opts.direction==="rtl";o_keyboard=$.extend({},opts.keyboard&&KEYBOARD_OPTIONS,opts.keyboard);updateThumbArrow(opts);var classes={add:[],remove:[]};function addOrRemoveClass(FLAG,value){classes[FLAG?"add":"remove"].push(value)}if(size>1){o_nav=opts.nav;o_navTop=opts.navposition==="top";classes.remove.push(selectClass);$arrs.toggle(opts.arrows)}else{o_nav=false;$arrs.hide()}arrsUpdate();stageWheelUpdate();thumbArrUpdate();if(opts.autoplay)setAutoplayInterval(opts.autoplay);o_thumbSide=numberFromMeasure(opts.thumbwidth)||THUMB_SIZE;o_thumbSide2=numberFromMeasure(opts.thumbheight)||THUMB_SIZE;stageWheelTail.ok=navWheelTail.ok=opts.trackpad&&!SLOW;stageNoMove();extendMeasures(opts,[measures]);o_navThumbs=o_nav==="thumbs";if($navWrap.filter(":hidden")&&!!o_nav){$navWrap.show()}if(o_navThumbs){frameDraw(size,"navThumb");$navFrame=$navThumbFrame;navFrameKey=NAV_THUMB_FRAME_KEY;setStyle($style,$.Fotorama.jst.style({w:o_thumbSide,h:o_thumbSide2,b:opts.thumbborderwidth,m:opts.thumbmargin,s:stamp,q:!COMPAT}));$nav.addClass(navThumbsClass).removeClass(navDotsClass)}else if(o_nav==="dots"){frameDraw(size,"navDot");$navFrame=$navDotFrame;navFrameKey=NAV_DOT_FRAME_KEY;$nav.addClass(navDotsClass).removeClass(navThumbsClass)}else{$navWrap.hide();o_nav=false;$nav.removeClass(navThumbsClass+" "+navDotsClass)}if(o_nav){if(o_navTop){$navWrap.insertBefore($stage)}else{$navWrap.insertAfter($stage)}frameAppend.nav=false;frameAppend($navFrame,$navShaft,"nav")}o_allowFullScreen=opts.allowfullscreen;if(o_allowFullScreen){$fullscreenIcon.prependTo($stage);o_nativeFullScreen=FULLSCREEN&&o_allowFullScreen==="native";stubEvent($fullscreenIcon,"touchend")}else{$fullscreenIcon.detach();o_nativeFullScreen=false}addOrRemoveClass(o_fade,wrapFadeClass);addOrRemoveClass(!o_fade,wrapSlideClass);addOrRemoveClass(!opts.captions,wrapNoCaptionsClass);addOrRemoveClass(o_rtl,wrapRtlClass);addOrRemoveClass(opts.arrows,wrapToggleArrowsClass);o_shadows=opts.shadows&&!SLOW;addOrRemoveClass(!o_shadows,wrapNoShadowsClass);$wrap.addClass(classes.add.join(" ")).removeClass(classes.remove.join(" "));lastOptions=$.extend({},opts);setStagePosition()}function normalizeIndex(index){return index<0?(size+index%size)%size:index>=size?index%size:index}function limitIndex(index){return minMaxLimit(index,0,size-1)}function edgeIndex(index){return o_loop?normalizeIndex(index):limitIndex(index)}function getPrevIndex(index){return index>0||o_loop?index-1:false}function getNextIndex(index){return index<size-1||o_loop?index+1:false}function setStageShaftMinmaxAndSnap(){stageShaftTouchTail.min=o_loop?-Infinity:-getPosByIndex(size-1,measures.w,opts.margin,repositionIndex);stageShaftTouchTail.max=o_loop?Infinity:-getPosByIndex(0,measures.w,opts.margin,repositionIndex);stageShaftTouchTail.snap=measures.w+opts.margin}function setNavShaftMinMax(){var isVerticalDir=opts.navdir==="vertical";var param=isVerticalDir?$navShaft.height():$navShaft.width();var mainParam=isVerticalDir?measures.h:measures.nw;navShaftTouchTail.min=Math.min(0,mainParam-param);navShaftTouchTail.max=0;navShaftTouchTail.direction=opts.navdir;$navShaft.toggleClass(grabClass,!(navShaftTouchTail.noMove=navShaftTouchTail.min===navShaftTouchTail.max))}function eachIndex(indexes,type,fn){if(typeof indexes==="number"){indexes=new Array(indexes);var rangeFLAG=true}return $.each(indexes,function(i,index){if(rangeFLAG)index=i;if(typeof index==="number"){var dataFrame=data[normalizeIndex(index)];if(dataFrame){var key="$"+type+"Frame",$frame=dataFrame[key];fn.call(this,i,index,dataFrame,$frame,key,$frame&&$frame.data())}}})}function setMeasures(width,height,ratio,index){if(!measuresSetFLAG||measuresSetFLAG==="*"&&index===startIndex){width=measureIsValid(opts.width)||measureIsValid(width)||WIDTH;height=measureIsValid(opts.height)||measureIsValid(height)||HEIGHT;that.resize({width:width,ratio:opts.ratio||ratio||width/height},0,index!==startIndex&&"*")}}function loadImg(indexes,type,specialMeasures,again){eachIndex(indexes,type,function(i,index,dataFrame,$frame,key,frameData){if(!$frame)return;var fullFLAG=that.fullScreen&&!frameData.$full&&type==="stage";if(frameData.$img&&!again&&!fullFLAG)return;var img=new Image,$img=$(img),imgData=$img.data();frameData[fullFLAG?"$full":"$img"]=$img;var srcKey=type==="stage"?fullFLAG?"full":"img":"thumb",src=dataFrame[srcKey],dummy=fullFLAG?dataFrame["img"]:dataFrame[type==="stage"?"thumb":"img"];if(type==="navThumb")$frame=frameData.$wrap;function triggerTriggerEvent(event){var _index=normalizeIndex(index);triggerEvent(event,{index:_index,src:src,frame:data[_index]})}function error(){$img.remove();$.Fotorama.cache[src]="error";if((!dataFrame.html||type!=="stage")&&dummy&&dummy!==src){dataFrame[srcKey]=src=dummy;frameData.$full=null;loadImg([index],type,specialMeasures,true)}else{if(src&&!dataFrame.html&&!fullFLAG){$frame.trigger("f:error").removeClass(loadingClass).addClass(errorClass);triggerTriggerEvent("error")}else if(type==="stage"){$frame.trigger("f:load").removeClass(loadingClass+" "+errorClass).addClass(loadedClass);triggerTriggerEvent("load");setMeasures()}frameData.state="error";if(size>1&&data[index]===dataFrame&&!dataFrame.html&&!dataFrame.deleted&&!dataFrame.video&&!fullFLAG){dataFrame.deleted=true;that.splice(index,1)}}}function loaded(){$.Fotorama.measures[src]=imgData.measures=$.Fotorama.measures[src]||{width:img.width,height:img.height,ratio:img.width/img.height};setMeasures(imgData.measures.width,imgData.measures.height,imgData.measures.ratio,index);$img.off("load error").addClass(""+(fullFLAG?imgFullClass:imgClass)).attr("aria-hidden","false").prependTo($frame);if($frame.hasClass(stageFrameClass)&&!$frame.hasClass(videoContainerClass)){$frame.attr("href",$img.attr("src"))}fit($img,($.isFunction(specialMeasures)?specialMeasures():specialMeasures)||measures);$.Fotorama.cache[src]=frameData.state="loaded";setTimeout(function(){$frame.trigger("f:load").removeClass(loadingClass+" "+errorClass).addClass(loadedClass+" "+(fullFLAG?loadedFullClass:loadedImgClass));if(type==="stage"){triggerTriggerEvent("load")}else if(dataFrame.thumbratio===AUTO||!dataFrame.thumbratio&&opts.thumbratio===AUTO){dataFrame.thumbratio=imgData.measures.ratio;reset()}},0)}if(!src){error();return}function waitAndLoad(){var _i=10;waitFor(function(){return!touchedFLAG||!_i--&&!SLOW},function(){loaded()})}if(!$.Fotorama.cache[src]){$.Fotorama.cache[src]="*";$img.on("load",waitAndLoad).on("error",error)}else{(function justWait(){if($.Fotorama.cache[src]==="error"){error()}else if($.Fotorama.cache[src]==="loaded"){setTimeout(waitAndLoad,0)}else{setTimeout(justWait,100)}})()}frameData.state="";img.src=src;if(frameData.data.caption){img.alt=frameData.data.caption||""}if(frameData.data.full){$(img).data("original",frameData.data.full)}if(UTIL.isExpectedCaption(dataFrame,opts.showcaption)){$(img).attr("aria-labelledby",dataFrame.labelledby)}})}function updateFotoramaState(){var $frame=activeFrame[STAGE_FRAME_KEY];if($frame&&!$frame.data().state){$spinner.addClass(spinnerShowClass);$frame.on("f:load f:error",function(){$frame.off("f:load f:error");$spinner.removeClass(spinnerShowClass)})}}function addNavFrameEvents(frame){addEnterUp(frame,onNavFrameClick);addFocus(frame,function(){setTimeout(function(){lockScroll($nav)},0);slideNavShaft({time:o_transitionDuration,guessIndex:$(this).data().eq,minMax:navShaftTouchTail})})}function frameDraw(indexes,type){eachIndex(indexes,type,function(i,index,dataFrame,$frame,key,frameData){if($frame)return;$frame=dataFrame[key]=$wrap[key].clone();frameData=$frame.data();frameData.data=dataFrame;var frame=$frame[0],labelledbyValue="labelledby"+$.now();if(type==="stage"){if(dataFrame.html){$('<div class="'+htmlClass+'"></div>').append(dataFrame._html?$(dataFrame.html).removeAttr("id").html(dataFrame._html):dataFrame.html).appendTo($frame)}if(dataFrame.id){labelledbyValue=dataFrame.id||labelledbyValue}dataFrame.labelledby=labelledbyValue;if(UTIL.isExpectedCaption(dataFrame,opts.showcaption)){$($.Fotorama.jst.frameCaption({caption:dataFrame.caption,labelledby:labelledbyValue})).appendTo($frame)}dataFrame.video&&$frame.addClass(stageFrameVideoClass).append($videoPlay.clone());addFocus(frame,function(){setTimeout(function(){lockScroll($stage)},0);clickToShow({index:frameData.eq,user:true})});$stageFrame=$stageFrame.add($frame)}else if(type==="navDot"){addNavFrameEvents(frame);$navDotFrame=$navDotFrame.add($frame)}else if(type==="navThumb"){addNavFrameEvents(frame);frameData.$wrap=$frame.children(":first");$navThumbFrame=$navThumbFrame.add($frame);if(dataFrame.video){frameData.$wrap.append($videoPlay.clone())}}})}function callFit($img,measuresToFit){return $img&&$img.length&&fit($img,measuresToFit)}function stageFramePosition(indexes){eachIndex(indexes,"stage",function(i,index,dataFrame,$frame,key,frameData){if(!$frame)return;var normalizedIndex=normalizeIndex(index);frameData.eq=normalizedIndex;toDetach[STAGE_FRAME_KEY][normalizedIndex]=$frame.css($.extend({left:o_fade?0:getPosByIndex(index,measures.w,opts.margin,repositionIndex)},o_fade&&getDuration(0)));if(isDetached($frame[0])){$frame.appendTo($stageShaft);unloadVideo(dataFrame.$video)}callFit(frameData.$img,measures);callFit(frameData.$full,measures);if($frame.hasClass(stageFrameClass)&&!($frame.attr("aria-hidden")==="false"&&$frame.hasClass(activeClass))){$frame.attr("aria-hidden","true")}})}function thumbsDraw(pos,loadFLAG){var leftLimit,rightLimit,exceedLimit;if(o_nav!=="thumbs"||isNaN(pos))return;leftLimit=-pos;rightLimit=-pos+measures.nw;if(opts.navdir==="vertical"){pos=pos-opts.thumbheight;rightLimit=-pos+measures.h}$navThumbFrame.each(function(){var $this=$(this),thisData=$this.data(),eq=thisData.eq,getSpecialMeasures=function(){return{h:o_thumbSide2,w:thisData.w}},specialMeasures=getSpecialMeasures(),exceedLimit=opts.navdir==="vertical"?thisData.t>rightLimit:thisData.l>rightLimit;specialMeasures.w=thisData.w;if(thisData.l+thisData.w<leftLimit||exceedLimit||callFit(thisData.$img,specialMeasures))return;loadFLAG&&loadImg([eq],"navThumb",getSpecialMeasures)})}function frameAppend($frames,$shaft,type){if(!frameAppend[type]){var thumbsFLAG=type==="nav"&&o_navThumbs,left=0,top=0;$shaft.append($frames.filter(function(){var actual,$this=$(this),frameData=$this.data();for(var _i=0,_l=data.length;_i<_l;_i++){if(frameData.data===data[_i]){actual=true;frameData.eq=_i;break}}return actual||$this.remove()&&false}).sort(function(a,b){return $(a).data().eq-$(b).data().eq}).each(function(){var $this=$(this),frameData=$this.data();UTIL.setThumbAttr($this,frameData.data.caption,"aria-label")}).each(function(){if(!thumbsFLAG)return;var $this=$(this),frameData=$this.data(),thumbwidth=Math.round(o_thumbSide2*frameData.data.thumbratio)||o_thumbSide,thumbheight=Math.round(o_thumbSide/frameData.data.thumbratio)||o_thumbSide2;frameData.t=top;frameData.h=thumbheight;frameData.l=left;frameData.w=thumbwidth;$this.css({width:thumbwidth});top+=thumbheight+opts.thumbmargin;left+=thumbwidth+opts.thumbmargin}));frameAppend[type]=true}}function getDirection(x){return x-stageLeft>measures.w/3}function disableDirrection(i){return!o_loop&&(!(activeIndex+i)||!(activeIndex-size+i))&&!$videoPlaying}function arrsUpdate(){var disablePrev=disableDirrection(0),disableNext=disableDirrection(1);$arrPrev.toggleClass(arrDisabledClass,disablePrev).attr(disableAttr(disablePrev,false));$arrNext.toggleClass(arrDisabledClass,disableNext).attr(disableAttr(disableNext,false))}function thumbArrUpdate(){var isLeftDisable=false,isRightDisable=false;if(opts.navtype==="thumbs"&&!opts.loop){activeIndex==0?isLeftDisable=true:isLeftDisable=false;activeIndex==opts.data.length-1?isRightDisable=true:isRightDisable=false}if(opts.navtype==="slides"){var pos=readPosition($navShaft,opts.navdir);pos>=navShaftTouchTail.max?isLeftDisable=true:isLeftDisable=false;pos<=navShaftTouchTail.min?isRightDisable=true:isRightDisable=false}$thumbArrLeft.toggleClass(arrDisabledClass,isLeftDisable).attr(disableAttr(isLeftDisable,true));$thumbArrRight.toggleClass(arrDisabledClass,isRightDisable).attr(disableAttr(isRightDisable,true))}function stageWheelUpdate(){if(stageWheelTail.ok){stageWheelTail.prevent={"<":disableDirrection(0),">":disableDirrection(1)}}}function getNavFrameBounds($navFrame){var navFrameData=$navFrame.data(),left,top,width,height;if(o_navThumbs){left=navFrameData.l;top=navFrameData.t;width=navFrameData.w;height=navFrameData.h}else{left=$navFrame.position().left;width=$navFrame.width()}var horizontalBounds={c:left+width/2,min:-left+opts.thumbmargin*10,max:-left+measures.w-width-opts.thumbmargin*10};var verticalBounds={c:top+height/2,min:-top+opts.thumbmargin*10,max:-top+measures.h-height-opts.thumbmargin*10};return opts.navdir==="vertical"?verticalBounds:horizontalBounds}function slideThumbBorder(time){var navFrameData=activeFrame[navFrameKey].data();slide($thumbBorder,{time:time*1.2,pos:opts.navdir==="vertical"?navFrameData.t:navFrameData.l,width:navFrameData.w,height:navFrameData.h,direction:opts.navdir})}function slideNavShaft(options){var $guessNavFrame=data[options.guessIndex][navFrameKey],typeOfAnimation=opts.navtype;var overflowFLAG,time,minMax,boundTop,boundLeft,l,pos,x;if($guessNavFrame){if(typeOfAnimation==="thumbs"){overflowFLAG=navShaftTouchTail.min!==navShaftTouchTail.max;minMax=options.minMax||overflowFLAG&&getNavFrameBounds(activeFrame[navFrameKey]);boundTop=overflowFLAG&&(options.keep&&slideNavShaft.t?slideNavShaft.l:minMaxLimit((options.coo||measures.nw/2)-getNavFrameBounds($guessNavFrame).c,minMax.min,minMax.max));boundLeft=overflowFLAG&&(options.keep&&slideNavShaft.l?slideNavShaft.l:minMaxLimit((options.coo||measures.nw/2)-getNavFrameBounds($guessNavFrame).c,minMax.min,minMax.max));l=opts.navdir==="vertical"?boundTop:boundLeft;pos=overflowFLAG&&minMaxLimit(l,navShaftTouchTail.min,navShaftTouchTail.max)||0;time=options.time*1.1;slide($navShaft,{time:time,pos:pos,direction:opts.navdir,onEnd:function(){thumbsDraw(pos,true);thumbArrUpdate()}});setShadow($nav,findShadowEdge(pos,navShaftTouchTail.min,navShaftTouchTail.max,opts.navdir));slideNavShaft.l=l}else{x=readPosition($navShaft,opts.navdir);time=options.time*1.11;pos=validateSlidePos(opts,navShaftTouchTail,options.guessIndex,x,$guessNavFrame,$navWrap,opts.navdir);slide($navShaft,{time:time,pos:pos,direction:opts.navdir,onEnd:function(){thumbsDraw(pos,true);thumbArrUpdate()}});setShadow($nav,findShadowEdge(pos,navShaftTouchTail.min,navShaftTouchTail.max,opts.navdir))}}}function navUpdate(){deactivateFrames(navFrameKey);toDeactivate[navFrameKey].push(activeFrame[navFrameKey].addClass(activeClass).attr("data-active",true))}function deactivateFrames(key){var _toDeactivate=toDeactivate[key];while(_toDeactivate.length){_toDeactivate.shift().removeClass(activeClass).attr("data-active",false)}}function detachFrames(key){var _toDetach=toDetach[key];$.each(activeIndexes,function(i,index){delete _toDetach[normalizeIndex(index)]});$.each(_toDetach,function(index,$frame){delete _toDetach[index];$frame.detach()})}function stageShaftReposition(skipOnEnd){repositionIndex=dirtyIndex=activeIndex;var $frame=activeFrame[STAGE_FRAME_KEY];if($frame){deactivateFrames(STAGE_FRAME_KEY);toDeactivate[STAGE_FRAME_KEY].push($frame.addClass(activeClass).attr("data-active",true));if($frame.hasClass(stageFrameClass)){$frame.attr("aria-hidden","false")}skipOnEnd||that.showStage.onEnd(true);stop($stageShaft,0,true);detachFrames(STAGE_FRAME_KEY);stageFramePosition(activeIndexes);setStageShaftMinmaxAndSnap();setNavShaftMinMax();addEnterUp($stageShaft[0],function(){if(!$fotorama.hasClass(fullscreenClass)){that.requestFullScreen();$fullscreenIcon.focus()}})}}function extendMeasures(options,measuresArray){if(!options)return;$.each(measuresArray,function(i,measures){if(!measures)return;$.extend(measures,{width:options.width||measures.width,height:options.height,minwidth:options.minwidth,maxwidth:options.maxwidth,minheight:options.minheight,maxheight:options.maxheight,ratio:getRatio(options.ratio)})})}function triggerEvent(event,extra){$fotorama.trigger(_fotoramaClass+":"+event,[that,extra])}function onTouchStart(){clearTimeout(onTouchEnd.t);touchedFLAG=1;if(opts.stopautoplayontouch){that.stopAutoplay()}else{pausedAutoplayFLAG=true}}function onTouchEnd(){if(!touchedFLAG)return;if(!opts.stopautoplayontouch){releaseAutoplay();changeAutoplay()}onTouchEnd.t=setTimeout(function(){touchedFLAG=0},TRANSITION_DURATION+TOUCH_TIMEOUT)}function releaseAutoplay(){pausedAutoplayFLAG=!!($videoPlaying||stoppedAutoplayFLAG)}function changeAutoplay(){clearTimeout(changeAutoplay.t);waitFor.stop(changeAutoplay.w);if(!opts.autoplay||pausedAutoplayFLAG){if(that.autoplay){that.autoplay=false;triggerEvent("stopautoplay")}return}if(!that.autoplay){that.autoplay=true;triggerEvent("startautoplay")}var _activeIndex=activeIndex;var frameData=activeFrame[STAGE_FRAME_KEY].data();changeAutoplay.w=waitFor(function(){return frameData.state||_activeIndex!==activeIndex},function(){changeAutoplay.t=setTimeout(function(){if(pausedAutoplayFLAG||_activeIndex!==activeIndex)return;var _nextAutoplayIndex=nextAutoplayIndex,nextFrameData=data[_nextAutoplayIndex][STAGE_FRAME_KEY].data();changeAutoplay.w=waitFor(function(){return nextFrameData.state||_nextAutoplayIndex!==nextAutoplayIndex},function(){if(pausedAutoplayFLAG||_nextAutoplayIndex!==nextAutoplayIndex)return;that.show(o_loop?getDirectionSign(!o_rtl):nextAutoplayIndex)})},opts.autoplay)})}that.startAutoplay=function(interval){if(that.autoplay)return this;pausedAutoplayFLAG=stoppedAutoplayFLAG=false;setAutoplayInterval(interval||opts.autoplay);changeAutoplay();return this};that.stopAutoplay=function(){if(that.autoplay){pausedAutoplayFLAG=stoppedAutoplayFLAG=true;changeAutoplay()}return this};that.showSlide=function(slideDir){var currentPosition=readPosition($navShaft,opts.navdir),pos,time=500*1.1,size=opts.navdir==="horizontal"?opts.thumbwidth:opts.thumbheight,onEnd=function(){thumbArrUpdate()};if(slideDir==="next"){pos=currentPosition-(size+opts.margin)*thumbsPerSlide}if(slideDir==="prev"){pos=currentPosition+(size+opts.margin)*thumbsPerSlide}pos=validateRestrictions(pos,navShaftTouchTail);thumbsDraw(pos,true);slide($navShaft,{time:time,pos:pos,direction:opts.navdir,onEnd:onEnd})};that.showWhileLongPress=function(options){if(that.longPress.singlePressInProgress){return}var index=calcActiveIndex(options);calcGlobalIndexes(index);var time=calcTime(options)/50;var _activeFrame=activeFrame;that.activeFrame=activeFrame=data[activeIndex];var silent=_activeFrame===activeFrame&&!options.user;that.showNav(silent,options,time);return this};that.showEndLongPress=function(options){if(that.longPress.singlePressInProgress){return}var index=calcActiveIndex(options);calcGlobalIndexes(index);var time=calcTime(options)/50;var _activeFrame=activeFrame;that.activeFrame=activeFrame=data[activeIndex];var silent=_activeFrame===activeFrame&&!options.user;that.showStage(silent,options,time);showedFLAG=typeof lastActiveIndex!=="undefined"&&lastActiveIndex!==activeIndex;lastActiveIndex=activeIndex;return this};function calcActiveIndex(options){var index;if(typeof options!=="object"){index=options;options={}}else{index=options.index}index=index===">"?dirtyIndex+1:index==="<"?dirtyIndex-1:index==="<<"?0:index===">>"?size-1:index;index=isNaN(index)?undefined:index;index=typeof index==="undefined"?activeIndex||0:index;return index}function calcGlobalIndexes(index){that.activeIndex=activeIndex=edgeIndex(index);prevIndex=getPrevIndex(activeIndex);nextIndex=getNextIndex(activeIndex);nextAutoplayIndex=normalizeIndex(activeIndex+(o_rtl?-1:1));activeIndexes=[activeIndex,prevIndex,nextIndex];dirtyIndex=o_loop?index:activeIndex}function calcTime(options){var diffIndex=Math.abs(lastActiveIndex-dirtyIndex),time=getNumber(options.time,function(){return Math.min(o_transitionDuration*(1+(diffIndex-1)/12),o_transitionDuration*2)});if(options.slow){time*=10}return time}that.showStage=function(silent,options,time){unloadVideo($videoPlaying,activeFrame.i!==data[normalizeIndex(repositionIndex)].i);frameDraw(activeIndexes,"stage");stageFramePosition(SLOW?[dirtyIndex]:[dirtyIndex,getPrevIndex(dirtyIndex),getNextIndex(dirtyIndex)]);updateTouchTails("go",true);silent||triggerEvent("show",{user:options.user,time:time});pausedAutoplayFLAG=true;var overPos=options.overPos;var onEnd=that.showStage.onEnd=function(skipReposition){if(onEnd.ok)return;onEnd.ok=true;skipReposition||stageShaftReposition(true);if(!silent){triggerEvent("showend",{user:options.user})}if(!skipReposition&&o_transition&&o_transition!==opts.transition){that.setOptions({transition:o_transition});o_transition=false;return}updateFotoramaState();loadImg(activeIndexes,"stage");updateTouchTails("go",false);stageWheelUpdate();stageCursor();releaseAutoplay();changeAutoplay();if(that.fullScreen){activeFrame[STAGE_FRAME_KEY].find("."+imgFullClass).attr("aria-hidden",false);activeFrame[STAGE_FRAME_KEY].find("."+imgClass).attr("aria-hidden",true)}else{activeFrame[STAGE_FRAME_KEY].find("."+imgFullClass).attr("aria-hidden",true);activeFrame[STAGE_FRAME_KEY].find("."+imgClass).attr("aria-hidden",false)}};if(!o_fade){slide($stageShaft,{pos:-getPosByIndex(dirtyIndex,measures.w,opts.margin,repositionIndex),overPos:overPos,time:time,onEnd:onEnd})}else{var $activeFrame=activeFrame[STAGE_FRAME_KEY],$prevActiveFrame=data[lastActiveIndex]&&activeIndex!==lastActiveIndex?data[lastActiveIndex][STAGE_FRAME_KEY]:null;fade($activeFrame,$prevActiveFrame,$stageFrame,{time:time,method:opts.transition,onEnd:onEnd},fadeStack)}arrsUpdate()};that.showNav=function(silent,options,time){thumbArrUpdate();if(o_nav){navUpdate();var guessIndex=limitIndex(activeIndex+minMaxLimit(dirtyIndex-lastActiveIndex,-1,1));slideNavShaft({time:time,coo:guessIndex!==activeIndex&&options.coo,guessIndex:typeof options.coo!=="undefined"?guessIndex:activeIndex,keep:silent});if(o_navThumbs)slideThumbBorder(time)}};that.show=function(options){that.longPress.singlePressInProgress=true;var index=calcActiveIndex(options);calcGlobalIndexes(index);var time=calcTime(options);var _activeFrame=activeFrame;that.activeFrame=activeFrame=data[activeIndex];var silent=_activeFrame===activeFrame&&!options.user;that.showStage(silent,options,time);that.showNav(silent,options,time);showedFLAG=typeof lastActiveIndex!=="undefined"&&lastActiveIndex!==activeIndex;lastActiveIndex=activeIndex;that.longPress.singlePressInProgress=false;return this};that.requestFullScreen=function(){if(o_allowFullScreen&&!that.fullScreen){var isVideo=$((that.activeFrame||{}).$stageFrame||{}).hasClass("fotorama-video-container");if(isVideo){return}scrollTop=$WINDOW.scrollTop();scrollLeft=$WINDOW.scrollLeft();lockScroll($WINDOW);updateTouchTails("x",true);measuresStash=$.extend({},measures);$fotorama.addClass(fullscreenClass).appendTo($BODY.addClass(_fullscreenClass));$HTML.addClass(_fullscreenClass);unloadVideo($videoPlaying,true,true);that.fullScreen=true;if(o_nativeFullScreen){fullScreenApi.request(fotorama)}that.resize();loadImg(activeIndexes,"stage");updateFotoramaState();triggerEvent("fullscreenenter");if(!("ontouchstart"in window)){$fullscreenIcon.focus()}}return this};function cancelFullScreen(){if(that.fullScreen){that.fullScreen=false;if(FULLSCREEN){fullScreenApi.cancel(fotorama)}$BODY.removeClass(_fullscreenClass);$HTML.removeClass(_fullscreenClass);$fotorama.removeClass(fullscreenClass).insertAfter($anchor);measures=$.extend({},measuresStash);unloadVideo($videoPlaying,true,true);updateTouchTails("x",false);that.resize();loadImg(activeIndexes,"stage");lockScroll($WINDOW,scrollLeft,scrollTop);triggerEvent("fullscreenexit")}}that.cancelFullScreen=function(){if(o_nativeFullScreen&&fullScreenApi.is()){fullScreenApi.cancel(document)}else{cancelFullScreen()}return this};that.toggleFullScreen=function(){return that[(that.fullScreen?"cancel":"request")+"FullScreen"]()};that.resize=function(options){if(!data)return this;var time=arguments[1]||0,setFLAG=arguments[2];thumbsPerSlide=getThumbsInSlide($wrap,opts);extendMeasures(!that.fullScreen?optionsToLowerCase(options):{width:$(window).width(),maxwidth:null,minwidth:null,height:$(window).height(),maxheight:null,minheight:null},[measures,setFLAG||that.fullScreen||opts]);var width=measures.width,height=measures.height,ratio=measures.ratio,windowHeight=$WINDOW.height()-(o_nav?$nav.height():0);if(measureIsValid(width)){$wrap.css({width:""});$wrap.css({height:""});$stage.css({width:""});$stage.css({height:""});$stageShaft.css({width:""});$stageShaft.css({height:""});$nav.css({width:""});$nav.css({height:""});$wrap.css({minWidth:measures.minwidth||0,maxWidth:measures.maxwidth||MAX_WIDTH});if(o_nav==="dots"){$navWrap.hide()}width=measures.W=measures.w=$wrap.width();measures.nw=o_nav&&numberFromWhatever(opts.navwidth,width)||width;$stageShaft.css({width:measures.w,marginLeft:(measures.W-measures.w)/2});height=numberFromWhatever(height,windowHeight);height=height||ratio&&width/ratio;if(height){width=Math.round(width);height=measures.h=Math.round(minMaxLimit(height,numberFromWhatever(measures.minheight,windowHeight),numberFromWhatever(measures.maxheight,windowHeight)));$stage.css({width:width,height:height});if(opts.navdir==="vertical"&&!that.fullscreen){$nav.width(opts.thumbwidth+opts.thumbmargin*2)}if(opts.navdir==="horizontal"&&!that.fullscreen){$nav.height(opts.thumbheight+opts.thumbmargin*2)}if(o_nav==="dots"){$nav.width(width).height("auto");$navWrap.show()}if(opts.navdir==="vertical"&&that.fullScreen){$stage.css("height",$WINDOW.height())}if(opts.navdir==="horizontal"&&that.fullScreen){$stage.css("height",$WINDOW.height()-$nav.height())}if(o_nav){switch(opts.navdir){case"vertical":$navWrap.removeClass(navShafthorizontalClass);$navWrap.removeClass(navShaftListClass);$navWrap.addClass(navShaftVerticalClass);$nav.stop().animate({height:measures.h,width:opts.thumbwidth},time);break;case"list":$navWrap.removeClass(navShaftVerticalClass);$navWrap.removeClass(navShafthorizontalClass);$navWrap.addClass(navShaftListClass);break;default:$navWrap.removeClass(navShaftVerticalClass);$navWrap.removeClass(navShaftListClass);$navWrap.addClass(navShafthorizontalClass);$nav.stop().animate({width:measures.nw},time);break}stageShaftReposition();slideNavShaft({guessIndex:activeIndex,time:time,keep:true});if(o_navThumbs&&frameAppend.nav)slideThumbBorder(time)}measuresSetFLAG=setFLAG||true;ready.ok=true;ready()}}stageLeft=$stage.offset().left;setStagePosition();return this};that.setOptions=function(options){$.extend(opts,options);reset();return this};that.shuffle=function(){data&&shuffle(data)&&reset();return this};function setShadow($el,edge){if(o_shadows){$el.removeClass(shadowsLeftClass+" "+shadowsRightClass);$el.removeClass(shadowsTopClass+" "+shadowsBottomClass);edge&&!$videoPlaying&&$el.addClass(edge.replace(/^|\s/g," "+shadowsClass+"--"))}}that.longPress={threshold:1,count:0,thumbSlideTime:20,progress:function(){if(!this.inProgress){this.count++;this.inProgress=this.count>this.threshold}},end:function(){if(this.inProgress){this.isEnded=true}},reset:function(){this.count=0;this.inProgress=false;this.isEnded=false}};that.destroy=function(){that.cancelFullScreen();that.stopAutoplay();data=that.data=null;appendElements();activeIndexes=[];detachFrames(STAGE_FRAME_KEY);reset.ok=false;return this};that.playVideo=function(){var dataFrame=activeFrame,video=dataFrame.video,_activeIndex=activeIndex;if(typeof video==="object"&&dataFrame.videoReady){o_nativeFullScreen&&that.fullScreen&&that.cancelFullScreen();waitFor(function(){return!fullScreenApi.is()||_activeIndex!==activeIndex},function(){if(_activeIndex===activeIndex){dataFrame.$video=dataFrame.$video||$(div(videoClass)).append(createVideoFrame(video));dataFrame.$video.appendTo(dataFrame[STAGE_FRAME_KEY]);$wrap.addClass(wrapVideoClass);$videoPlaying=dataFrame.$video;stageNoMove();$arrs.blur();$fullscreenIcon.blur();triggerEvent("loadvideo")}})}return this};that.stopVideo=function(){unloadVideo($videoPlaying,true,true);return this};that.spliceByIndex=function(index,newImgObj){newImgObj.i=index+1;newImgObj.img&&$.ajax({url:newImgObj.img,type:"HEAD",success:function(){data.splice(index,1,newImgObj);reset()}})};function unloadVideo($video,unloadActiveFLAG,releaseAutoplayFLAG){if(unloadActiveFLAG){$wrap.removeClass(wrapVideoClass);$videoPlaying=false;stageNoMove()}if($video&&$video!==$videoPlaying){$video.remove();triggerEvent("unloadvideo")}if(releaseAutoplayFLAG){releaseAutoplay();changeAutoplay()}}function toggleControlsClass(FLAG){$wrap.toggleClass(wrapNoControlsClass,FLAG)}function stageCursor(e){if(stageShaftTouchTail.flow)return;var x=e?e.pageX:stageCursor.x,pointerFLAG=x&&!disableDirrection(getDirection(x))&&opts.click;if(stageCursor.p!==pointerFLAG&&$stage.toggleClass(pointerClass,pointerFLAG)){stageCursor.p=pointerFLAG;stageCursor.x=x}}$stage.on("mousemove",stageCursor);function clickToShow(showOptions){clearTimeout(clickToShow.t);if(opts.clicktransition&&opts.clicktransition!==opts.transition){setTimeout(function(){var _o_transition=opts.transition;that.setOptions({transition:opts.clicktransition});o_transition=_o_transition;clickToShow.t=setTimeout(function(){that.show(showOptions)},10)},0)}else{that.show(showOptions)}}function onStageTap(e,toggleControlsFLAG){var target=e.target,$target=$(target);if($target.hasClass(videoPlayClass)){that.playVideo()}else if(target===fullscreenIcon){that.toggleFullScreen()}else if($videoPlaying){target===videoClose&&unloadVideo($videoPlaying,true,true)}else if(!$fotorama.hasClass(fullscreenClass)){that.requestFullScreen()}}function updateTouchTails(key,value){stageShaftTouchTail[key]=navShaftTouchTail[key]=value}stageShaftTouchTail=moveOnTouch($stageShaft,{onStart:onTouchStart,onMove:function(e,result){setShadow($stage,result.edge)},onTouchEnd:onTouchEnd,onEnd:function(result){var toggleControlsFLAG;setShadow($stage);toggleControlsFLAG=(MS_POINTER&&!hoverFLAG||result.touch)&&opts.arrows;if((result.moved||toggleControlsFLAG&&result.pos!==result.newPos&&!result.control)&&result.$target[0]!==$fullscreenIcon[0]){var index=getIndexByPos(result.newPos,measures.w,opts.margin,repositionIndex);that.show({index:index,time:o_fade?o_transitionDuration:result.time,overPos:result.overPos,user:true})}else if(!result.aborted&&!result.control){onStageTap(result.startEvent,toggleControlsFLAG)}},timeLow:1,timeHigh:1,friction:2,select:"."+selectClass+", ."+selectClass+" *",$wrap:$stage,direction:"horizontal"});navShaftTouchTail=moveOnTouch($navShaft,{onStart:onTouchStart,onMove:function(e,result){setShadow($nav,result.edge)},onTouchEnd:onTouchEnd,onEnd:function(result){function onEnd(){slideNavShaft.l=result.newPos;releaseAutoplay();changeAutoplay();thumbsDraw(result.newPos,true);thumbArrUpdate()}if(!result.moved){var target=result.$target.closest("."+navFrameClass,$navShaft)[0];target&&onNavFrameClick.call(target,result.startEvent)}else if(result.pos!==result.newPos){pausedAutoplayFLAG=true;slide($navShaft,{time:result.time,pos:result.newPos,overPos:result.overPos,direction:opts.navdir,onEnd:onEnd});thumbsDraw(result.newPos);o_shadows&&setShadow($nav,findShadowEdge(result.newPos,navShaftTouchTail.min,navShaftTouchTail.max,result.dir))}else{onEnd()}},timeLow:.5,timeHigh:2,friction:5,$wrap:$nav,direction:opts.navdir});stageWheelTail=wheel($stage,{shift:true,onEnd:function(e,direction){onTouchStart();onTouchEnd();that.show({index:direction,slow:e.altKey})}});navWheelTail=wheel($nav,{onEnd:function(e,direction){onTouchStart();onTouchEnd();var newPos=stop($navShaft)+direction*.25;$navShaft.css(getTranslate(minMaxLimit(newPos,navShaftTouchTail.min,navShaftTouchTail.max),opts.navdir));o_shadows&&setShadow($nav,findShadowEdge(newPos,navShaftTouchTail.min,navShaftTouchTail.max,opts.navdir));navWheelTail.prevent={"<":newPos>=navShaftTouchTail.max,">":newPos<=navShaftTouchTail.min};clearTimeout(navWheelTail.t);navWheelTail.t=setTimeout(function(){slideNavShaft.l=newPos;thumbsDraw(newPos,true)},TOUCH_TIMEOUT);thumbsDraw(newPos)}});$wrap.hover(function(){setTimeout(function(){if(touchedFLAG)return;toggleControlsClass(!(hoverFLAG=true))},0)},function(){if(!hoverFLAG)return;toggleControlsClass(!(hoverFLAG=false))});function onNavFrameClick(e){var index=$(this).data().eq;if(opts.navtype==="thumbs"){clickToShow({index:index,slow:e.altKey,user:true,coo:e._x-$nav.offset().left})}else{clickToShow({index:index,slow:e.altKey,user:true})}}function onArrClick(e){clickToShow({index:$arrs.index(this)?">":"<",slow:e.altKey,user:true})}smartClick($arrs,function(e){stopEvent(e);onArrClick.call(this,e)},{onStart:function(){onTouchStart();stageShaftTouchTail.control=true},onTouchEnd:onTouchEnd});smartClick($thumbArrLeft,function(e){stopEvent(e);if(opts.navtype==="thumbs"){that.show("<")}else{that.showSlide("prev")}});smartClick($thumbArrRight,function(e){stopEvent(e);if(opts.navtype==="thumbs"){that.show(">")}else{that.showSlide("next")}});function addFocusOnControls(el){addFocus(el,function(){setTimeout(function(){lockScroll($stage)},0);toggleControlsClass(false)})}$arrs.each(function(){addEnterUp(this,function(e){onArrClick.call(this,e)});addFocusOnControls(this)});addEnterUp(fullscreenIcon,function(){if($fotorama.hasClass(fullscreenClass)){that.cancelFullScreen();$stageShaft.focus()}else{that.requestFullScreen();$fullscreenIcon.focus()}});addFocusOnControls(fullscreenIcon);function reset(){setData();setOptions();if(!reset.i){reset.i=true;var _startindex=opts.startindex;activeIndex=repositionIndex=dirtyIndex=lastActiveIndex=startIndex=edgeIndex(_startindex)||0}if(size){if(changeToRtl())return;if($videoPlaying){unloadVideo($videoPlaying,true)}activeIndexes=[];detachFrames(STAGE_FRAME_KEY);reset.ok=true;that.show({index:activeIndex,time:0});that.resize()}else{that.destroy()}}function changeToRtl(){if(!changeToRtl.f===o_rtl){changeToRtl.f=o_rtl;activeIndex=size-1-activeIndex;that.reverse();return true}}$.each("load push pop shift unshift reverse sort splice".split(" "),function(i,method){that[method]=function(){data=data||[];if(method!=="load"){Array.prototype[method].apply(data,arguments)}else if(arguments[0]&&typeof arguments[0]==="object"&&arguments[0].length){data=clone(arguments[0])}reset();return that}});function ready(){if(ready.ok){ready.ok=false;triggerEvent("ready")}}reset()};$.fn.fotorama=function(opts){return this.each(function(){var that=this,$fotorama=$(this),fotoramaData=$fotorama.data(),fotorama=fotoramaData.fotorama;if(!fotorama){waitFor(function(){return!isHidden(that)},function(){fotoramaData.urtext=$fotorama.html();new $.Fotorama($fotorama,$.extend({},OPTIONS,window.fotoramaDefaults,opts,fotoramaData))})}else{fotorama.setOptions(opts,true)}})};$.Fotorama.instances=[];function calculateIndexes(){$.each($.Fotorama.instances,function(index,instance){instance.index=index})}function addInstance(instance){$.Fotorama.instances.push(instance);calculateIndexes()}function hideInstance(instance){$.Fotorama.instances.splice(instance.index,1);calculateIndexes()}$.Fotorama.cache={};$.Fotorama.measures={};$=$||{};$.Fotorama=$.Fotorama||{};$.Fotorama.jst=$.Fotorama.jst||{};$.Fotorama.jst.dots=function(v){var __t,__p="",__e=_.escape;__p+='<div class="fotorama__nav__frame fotorama__nav__frame--dot" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n <div class="fotorama__dot"></div>\r\n</div>';return __p};$.Fotorama.jst.frameCaption=function(v){var __t,__p="",__e=_.escape;__p+='<div class="fotorama__caption" aria-hidden="true">\r\n <div class="fotorama__caption__wrap" id="'+((__t=v.labelledby)==null?"":__t)+'">'+((__t=v.caption)==null?"":__t)+"</div>\r\n</div>\r\n";return __p};$.Fotorama.jst.style=function(v){var __t,__p="",__e=_.escape;__p+=".fotorama"+((__t=v.s)==null?"":__t)+" .fotorama__nav--thumbs .fotorama__nav__frame{\r\npadding:"+((__t=v.m)==null?"":__t)+"px;\r\nheight:"+((__t=v.h)==null?"":__t)+"px}\r\n.fotorama"+((__t=v.s)==null?"":__t)+" .fotorama__thumb-border{\r\nheight:"+((__t=v.h)==null?"":__t)+"px;\r\nborder-width:"+((__t=v.b)==null?"":__t)+"px;\r\nmargin-top:"+((__t=v.m)==null?"":__t)+"px}";return __p};$.Fotorama.jst.thumb=function(v){var __t,__p="",__e=_.escape;__p+='<div class="fotorama__nav__frame fotorama__nav__frame--thumb" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n <div class="fotorama__thumb">\r\n </div>\r\n</div>';return __p}})(window,document,location,typeof jQuery!=="undefined"&&jQuery); +fotoramaVersion="4.6.4";(function(window,document,location,$,undefined){"use strict";var _fotoramaClass="fotorama",_fullscreenClass="fotorama__fullscreen",wrapClass=_fotoramaClass+"__wrap",wrapCss2Class=wrapClass+"--css2",wrapCss3Class=wrapClass+"--css3",wrapVideoClass=wrapClass+"--video",wrapFadeClass=wrapClass+"--fade",wrapSlideClass=wrapClass+"--slide",wrapNoControlsClass=wrapClass+"--no-controls",wrapNoShadowsClass=wrapClass+"--no-shadows",wrapPanYClass=wrapClass+"--pan-y",wrapRtlClass=wrapClass+"--rtl",wrapOnlyActiveClass=wrapClass+"--only-active",wrapNoCaptionsClass=wrapClass+"--no-captions",wrapToggleArrowsClass=wrapClass+"--toggle-arrows",stageClass=_fotoramaClass+"__stage",stageFrameClass=stageClass+"__frame",stageFrameVideoClass=stageFrameClass+"--video",stageShaftClass=stageClass+"__shaft",grabClass=_fotoramaClass+"__grab",pointerClass=_fotoramaClass+"__pointer",arrClass=_fotoramaClass+"__arr",arrDisabledClass=arrClass+"--disabled",arrPrevClass=arrClass+"--prev",arrNextClass=arrClass+"--next",navClass=_fotoramaClass+"__nav",navWrapClass=navClass+"-wrap",navShaftClass=navClass+"__shaft",navShaftVerticalClass=navWrapClass+"--vertical",navShaftListClass=navWrapClass+"--list",navShafthorizontalClass=navWrapClass+"--horizontal",navDotsClass=navClass+"--dots",navThumbsClass=navClass+"--thumbs",navFrameClass=navClass+"__frame",fadeClass=_fotoramaClass+"__fade",fadeFrontClass=fadeClass+"-front",fadeRearClass=fadeClass+"-rear",shadowClass=_fotoramaClass+"__shadow",shadowsClass=shadowClass+"s",shadowsLeftClass=shadowsClass+"--left",shadowsRightClass=shadowsClass+"--right",shadowsTopClass=shadowsClass+"--top",shadowsBottomClass=shadowsClass+"--bottom",activeClass=_fotoramaClass+"__active",selectClass=_fotoramaClass+"__select",hiddenClass=_fotoramaClass+"--hidden",fullscreenClass=_fotoramaClass+"--fullscreen",fullscreenIconClass=_fotoramaClass+"__fullscreen-icon",errorClass=_fotoramaClass+"__error",loadingClass=_fotoramaClass+"__loading",loadedClass=_fotoramaClass+"__loaded",loadedFullClass=loadedClass+"--full",loadedImgClass=loadedClass+"--img",grabbingClass=_fotoramaClass+"__grabbing",imgClass=_fotoramaClass+"__img",imgFullClass=imgClass+"--full",thumbClass=_fotoramaClass+"__thumb",thumbArrLeft=thumbClass+"__arr--left",thumbArrRight=thumbClass+"__arr--right",thumbBorderClass=thumbClass+"-border",htmlClass=_fotoramaClass+"__html",videoContainerClass=_fotoramaClass+"-video-container",videoClass=_fotoramaClass+"__video",videoPlayClass=videoClass+"-play",videoCloseClass=videoClass+"-close",horizontalImageClass=_fotoramaClass+"_horizontal_ratio",verticalImageClass=_fotoramaClass+"_vertical_ratio",fotoramaSpinnerClass=_fotoramaClass+"__spinner",spinnerShowClass=fotoramaSpinnerClass+"--show";var JQUERY_VERSION=$&&$.fn.jquery.split(".");if(!JQUERY_VERSION||JQUERY_VERSION[0]<1||JQUERY_VERSION[0]==1&&JQUERY_VERSION[1]<8){throw"Fotorama requires jQuery 1.8 or later and will not run without it."}var _={};var Modernizr=function(window,document,undefined){var version="2.8.3",Modernizr={},docElement=document.documentElement,mod="modernizr",modElem=document.createElement(mod),mStyle=modElem.style,inputElem,toString={}.toString,prefixes=" -webkit- -moz- -o- -ms- ".split(" "),omPrefixes="Webkit Moz O ms",cssomPrefixes=omPrefixes.split(" "),domPrefixes=omPrefixes.toLowerCase().split(" "),tests={},inputs={},attrs={},classes=[],slice=classes.slice,featureName,injectElementWithStyles=function(rule,callback,nodes,testnames){var style,ret,node,docOverflow,div=document.createElement("div"),body=document.body,fakeBody=body||document.createElement("body");if(parseInt(nodes,10)){while(nodes--){node=document.createElement("div");node.id=testnames?testnames[nodes]:mod+(nodes+1);div.appendChild(node)}}style=["­",'<style id="s',mod,'">',rule,"</style>"].join("");div.id=mod;(body?div:fakeBody).innerHTML+=style;fakeBody.appendChild(div);if(!body){fakeBody.style.background="";fakeBody.style.overflow="hidden";docOverflow=docElement.style.overflow;docElement.style.overflow="hidden";docElement.appendChild(fakeBody)}ret=callback(div,rule);if(!body){fakeBody.parentNode.removeChild(fakeBody);docElement.style.overflow=docOverflow}else{div.parentNode.removeChild(div)}return!!ret},_hasOwnProperty={}.hasOwnProperty,hasOwnProp;if(!is(_hasOwnProperty,"undefined")&&!is(_hasOwnProperty.call,"undefined")){hasOwnProp=function(object,property){return _hasOwnProperty.call(object,property)}}else{hasOwnProp=function(object,property){return property in object&&is(object.constructor.prototype[property],"undefined")}}if(!Function.prototype.bind){Function.prototype.bind=function bind(that){var target=this;if(typeof target!="function"){throw new TypeError}var args=slice.call(arguments,1),bound=function(){if(this instanceof bound){var F=function(){};F.prototype=target.prototype;var self=new F;var result=target.apply(self,args.concat(slice.call(arguments)));if(Object(result)===result){return result}return self}else{return target.apply(that,args.concat(slice.call(arguments)))}};return bound}}function setCss(str){mStyle.cssText=str}function setCssAll(str1,str2){return setCss(prefixes.join(str1+";")+(str2||""))}function is(obj,type){return typeof obj===type}function contains(str,substr){return!!~(""+str).indexOf(substr)}function testProps(props,prefixed){for(var i in props){var prop=props[i];if(!contains(prop,"-")&&mStyle[prop]!==undefined){return prefixed=="pfx"?prop:true}}return false}function testDOMProps(props,obj,elem){for(var i in props){var item=obj[props[i]];if(item!==undefined){if(elem===false)return props[i];if(is(item,"function")){return item.bind(elem||obj)}return item}}return false}function testPropsAll(prop,prefixed,elem){var ucProp=prop.charAt(0).toUpperCase()+prop.slice(1),props=(prop+" "+cssomPrefixes.join(ucProp+" ")+ucProp).split(" ");if(is(prefixed,"string")||is(prefixed,"undefined")){return testProps(props,prefixed)}else{props=(prop+" "+domPrefixes.join(ucProp+" ")+ucProp).split(" ");return testDOMProps(props,prefixed,elem)}}tests["touch"]=function(){var bool;if("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch){bool=true}else{injectElementWithStyles(["@media (",prefixes.join("touch-enabled),("),mod,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(node){bool=node.offsetTop===9})}return bool};tests["csstransforms3d"]=function(){var ret=!!testPropsAll("perspective");if(ret&&"webkitPerspective"in docElement.style){injectElementWithStyles("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(node,rule){ret=node.offsetLeft===9&&node.offsetHeight===3})}return ret};tests["csstransitions"]=function(){return testPropsAll("transition")};for(var feature in tests){if(hasOwnProp(tests,feature)){featureName=feature.toLowerCase();Modernizr[featureName]=tests[feature]();classes.push((Modernizr[featureName]?"":"no-")+featureName)}}Modernizr.addTest=function(feature,test){if(typeof feature=="object"){for(var key in feature){if(hasOwnProp(feature,key)){Modernizr.addTest(key,feature[key])}}}else{feature=feature.toLowerCase();if(Modernizr[feature]!==undefined){return Modernizr}test=typeof test=="function"?test():test;if(typeof enableClasses!=="undefined"&&enableClasses){docElement.className+=" "+(test?"":"no-")+feature}Modernizr[feature]=test}return Modernizr};setCss("");modElem=inputElem=null;Modernizr._version=version;Modernizr._prefixes=prefixes;Modernizr._domPrefixes=domPrefixes;Modernizr._cssomPrefixes=cssomPrefixes;Modernizr.testProp=function(prop){return testProps([prop])};Modernizr.testAllProps=testPropsAll;Modernizr.testStyles=injectElementWithStyles;Modernizr.prefixed=function(prop,obj,elem){if(!obj){return testPropsAll(prop,"pfx")}else{return testPropsAll(prop,obj,elem)}};return Modernizr}(window,document);var fullScreenApi={ok:false,is:function(){return false},request:function(){},cancel:function(){},event:"",prefix:""},browserPrefixes="webkit moz o ms khtml".split(" ");if(typeof document.cancelFullScreen!="undefined"){fullScreenApi.ok=true}else{for(var i=0,il=browserPrefixes.length;i<il;i++){fullScreenApi.prefix=browserPrefixes[i];if(typeof document[fullScreenApi.prefix+"CancelFullScreen"]!="undefined"){fullScreenApi.ok=true;break}}}if(fullScreenApi.ok){fullScreenApi.event=fullScreenApi.prefix+"fullscreenchange";fullScreenApi.is=function(){switch(this.prefix){case"":return document.fullScreen;case"webkit":return document.webkitIsFullScreen;default:return document[this.prefix+"FullScreen"]}};fullScreenApi.request=function(el){return this.prefix===""?el.requestFullScreen():el[this.prefix+"RequestFullScreen"]()};fullScreenApi.cancel=function(el){return this.prefix===""?document.cancelFullScreen():document[this.prefix+"CancelFullScreen"]()}}function bez(coOrdArray){var encodedFuncName="bez_"+$.makeArray(arguments).join("_").replace(".","p");if(typeof $["easing"][encodedFuncName]!=="function"){var polyBez=function(p1,p2){var A=[null,null],B=[null,null],C=[null,null],bezCoOrd=function(t,ax){C[ax]=3*p1[ax];B[ax]=3*(p2[ax]-p1[ax])-C[ax];A[ax]=1-C[ax]-B[ax];return t*(C[ax]+t*(B[ax]+t*A[ax]))},xDeriv=function(t){return C[0]+t*(2*B[0]+3*A[0]*t)},xForT=function(t){var x=t,i=0,z;while(++i<14){z=bezCoOrd(x,0)-t;if(Math.abs(z)<.001)break;x-=z/xDeriv(x)}return x};return function(t){return bezCoOrd(xForT(t),1)}};$["easing"][encodedFuncName]=function(x,t,b,c,d){return c*polyBez([coOrdArray[0],coOrdArray[1]],[coOrdArray[2],coOrdArray[3]])(t/d)+b}}return encodedFuncName}var $WINDOW=$(window),$DOCUMENT=$(document),$HTML,$BODY,QUIRKS_FORCE=location.hash.replace("#","")==="quirks",TRANSFORMS3D=Modernizr.csstransforms3d,CSS3=TRANSFORMS3D&&!QUIRKS_FORCE,COMPAT=TRANSFORMS3D||document.compatMode==="CSS1Compat",FULLSCREEN=fullScreenApi.ok,MOBILE=navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i),SLOW=!CSS3||MOBILE,MS_POINTER=navigator.msPointerEnabled,WHEEL="onwheel"in document.createElement("div")?"wheel":document.onmousewheel!==undefined?"mousewheel":"DOMMouseScroll",TOUCH_TIMEOUT=250,TRANSITION_DURATION=300,SCROLL_LOCK_TIMEOUT=1400,AUTOPLAY_INTERVAL=5e3,MARGIN=2,THUMB_SIZE=64,WIDTH=500,HEIGHT=333,STAGE_FRAME_KEY="$stageFrame",NAV_DOT_FRAME_KEY="$navDotFrame",NAV_THUMB_FRAME_KEY="$navThumbFrame",AUTO="auto",BEZIER=bez([.1,0,.25,1]),MAX_WIDTH=1200,thumbsPerSlide=1,OPTIONS={width:null,minwidth:null,maxwidth:"100%",height:null,minheight:null,maxheight:null,ratio:null,margin:MARGIN,nav:"dots",navposition:"bottom",navwidth:null,thumbwidth:THUMB_SIZE,thumbheight:THUMB_SIZE,thumbmargin:MARGIN,thumbborderwidth:MARGIN,allowfullscreen:false,transition:"slide",clicktransition:null,transitionduration:TRANSITION_DURATION,captions:true,startindex:0,loop:false,autoplay:false,stopautoplayontouch:true,keyboard:false,arrows:true,click:true,swipe:false,trackpad:false,shuffle:false,direction:"ltr",shadows:true,showcaption:true,navdir:"horizontal",navarrows:true,navtype:"thumbs"},KEYBOARD_OPTIONS={left:true,right:true,down:true,up:true,space:false,home:false,end:false};function noop(){}function minMaxLimit(value,min,max){return Math.max(isNaN(min)?-Infinity:min,Math.min(isNaN(max)?Infinity:max,value))}function readTransform(css,dir){return css.match(/ma/)&&css.match(/-?\d+(?!d)/g)[css.match(/3d/)?dir==="vertical"?13:12:dir==="vertical"?5:4]}function readPosition($el,dir){if(CSS3){return+readTransform($el.css("transform"),dir)}else{return+$el.css(dir==="vertical"?"top":"left").replace("px","")}}function getTranslate(pos,direction){var obj={};if(CSS3){switch(direction){case"vertical":obj.transform="translate3d(0, "+pos+"px,0)";break;case"list":break;default:obj.transform="translate3d("+pos+"px,0,0)";break}}else{direction==="vertical"?obj.top=pos:obj.left=pos}return obj}function getDuration(time){return{"transition-duration":time+"ms"}}function unlessNaN(value,alternative){return isNaN(value)?alternative:value}function numberFromMeasure(value,measure){return unlessNaN(+String(value).replace(measure||"px",""))}function numberFromPercent(value){return/%$/.test(value)?numberFromMeasure(value,"%"):undefined}function numberFromWhatever(value,whole){return unlessNaN(numberFromPercent(value)/100*whole,numberFromMeasure(value))}function measureIsValid(value){return(!isNaN(numberFromMeasure(value))||!isNaN(numberFromMeasure(value,"%")))&&value}function getPosByIndex(index,side,margin,baseIndex){return(index-(baseIndex||0))*(side+(margin||0))}function getIndexByPos(pos,side,margin,baseIndex){return-Math.round(pos/(side+(margin||0))-(baseIndex||0))}function bindTransitionEnd($el){var elData=$el.data();if(elData.tEnd)return;var el=$el[0],transitionEndEvent={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",msTransition:"MSTransitionEnd",transition:"transitionend"};addEvent(el,transitionEndEvent[Modernizr.prefixed("transition")],function(e){elData.tProp&&e.propertyName.match(elData.tProp)&&elData.onEndFn()});elData.tEnd=true}function afterTransition($el,property,fn,time){var ok,elData=$el.data();if(elData){elData.onEndFn=function(){if(ok)return;ok=true;clearTimeout(elData.tT);fn()};elData.tProp=property;clearTimeout(elData.tT);elData.tT=setTimeout(function(){elData.onEndFn()},time*1.5);bindTransitionEnd($el)}}function stop($el,pos){var dir=$el.navdir||"horizontal";if($el.length){var elData=$el.data();if(CSS3){$el.css(getDuration(0));elData.onEndFn=noop;clearTimeout(elData.tT)}else{$el.stop()}var lockedPos=getNumber(pos,function(){return readPosition($el,dir)});$el.css(getTranslate(lockedPos,dir));return lockedPos}}function getNumber(){var number;for(var _i=0,_l=arguments.length;_i<_l;_i++){number=_i?arguments[_i]():arguments[_i];if(typeof number==="number"){break}}return number}function edgeResistance(pos,edge){return Math.round(pos+(edge-pos)/1.5)}function getProtocol(){getProtocol.p=getProtocol.p||(location.protocol==="https:"?"https://":"http://");return getProtocol.p}function parseHref(href){var a=document.createElement("a");a.href=href;return a}function findVideoId(href,forceVideo){if(typeof href!=="string")return href;href=parseHref(href);var id,type;if(href.host.match(/youtube\.com/)&&href.search){id=href.search.split("v=")[1];if(id){var ampersandPosition=id.indexOf("&");if(ampersandPosition!==-1){id=id.substring(0,ampersandPosition)}type="youtube"}}else if(href.host.match(/youtube\.com|youtu\.be/)){id=href.pathname.replace(/^\/(embed\/|v\/)?/,"").replace(/\/.*/,"");type="youtube"}else if(href.host.match(/vimeo\.com/)){type="vimeo";id=href.pathname.replace(/^\/(video\/)?/,"").replace(/\/.*/,"")}if((!id||!type)&&forceVideo){id=href.href;type="custom"}return id?{id:id,type:type,s:href.search.replace(/^\?/,""),p:getProtocol()}:false}function getVideoThumbs(dataFrame,data,fotorama){var img,thumb,video=dataFrame.video;if(video.type==="youtube"){thumb=getProtocol()+"img.youtube.com/vi/"+video.id+"/default.jpg";img=thumb.replace(/\/default.jpg$/,"/hqdefault.jpg");dataFrame.thumbsReady=true}else if(video.type==="vimeo"){$.ajax({url:getProtocol()+"vimeo.com/api/v2/video/"+video.id+".json",dataType:"jsonp",success:function(json){dataFrame.thumbsReady=true;updateData(data,{img:json[0].thumbnail_large,thumb:json[0].thumbnail_small},dataFrame.i,fotorama)}})}else{dataFrame.thumbsReady=true}return{img:img,thumb:thumb}}function updateData(data,_dataFrame,i,fotorama){for(var _i=0,_l=data.length;_i<_l;_i++){var dataFrame=data[_i];if(dataFrame.i===i&&dataFrame.thumbsReady){var clear={videoReady:true};clear[STAGE_FRAME_KEY]=clear[NAV_THUMB_FRAME_KEY]=clear[NAV_DOT_FRAME_KEY]=false;fotorama.splice(_i,1,$.extend({},dataFrame,clear,_dataFrame));break}}}function getDataFromHtml($el){var data=[];function getDataFromImg($img,imgData,checkVideo){var $child=$img.children("img").eq(0),_imgHref=$img.attr("href"),_imgSrc=$img.attr("src"),_thumbSrc=$child.attr("src"),_video=imgData.video,video=checkVideo?findVideoId(_imgHref,_video===true):false;if(video){_imgHref=false}else{video=_video}getDimensions($img,$child,$.extend(imgData,{video:video,img:imgData.img||_imgHref||_imgSrc||_thumbSrc,thumb:imgData.thumb||_thumbSrc||_imgSrc||_imgHref}))}function getDimensions($img,$child,imgData){var separateThumbFLAG=imgData.thumb&&imgData.img!==imgData.thumb,width=numberFromMeasure(imgData.width||$img.attr("width")),height=numberFromMeasure(imgData.height||$img.attr("height"));$.extend(imgData,{width:width,height:height,thumbratio:getRatio(imgData.thumbratio||numberFromMeasure(imgData.thumbwidth||$child&&$child.attr("width")||separateThumbFLAG||width)/numberFromMeasure(imgData.thumbheight||$child&&$child.attr("height")||separateThumbFLAG||height))})}$el.children().each(function(){var $this=$(this),dataFrame=optionsToLowerCase($.extend($this.data(),{id:$this.attr("id")}));if($this.is("a, img")){getDataFromImg($this,dataFrame,true)}else if(!$this.is(":empty")){getDimensions($this,null,$.extend(dataFrame,{html:this,_html:$this.html()}))}else return;data.push(dataFrame)});return data}function isHidden(el){return el.offsetWidth===0&&el.offsetHeight===0}function isDetached(el){return!$.contains(document.documentElement,el)}function waitFor(test,fn,timeout,i){if(!waitFor.i){waitFor.i=1;waitFor.ii=[true]}i=i||waitFor.i;if(typeof waitFor.ii[i]==="undefined"){waitFor.ii[i]=true}if(test()){fn()}else{waitFor.ii[i]&&setTimeout(function(){waitFor.ii[i]&&waitFor(test,fn,timeout,i)},timeout||100)}return waitFor.i++}waitFor.stop=function(i){waitFor.ii[i]=false};function fit($el,measuresToFit){var elData=$el.data(),measures=elData.measures;if(measures&&(!elData.l||elData.l.W!==measures.width||elData.l.H!==measures.height||elData.l.r!==measures.ratio||elData.l.w!==measuresToFit.w||elData.l.h!==measuresToFit.h)){var height=minMaxLimit(measuresToFit.h,0,measures.height),width=height*measures.ratio;UTIL.setRatio($el,width,height);elData.l={W:measures.width,H:measures.height,r:measures.ratio,w:measuresToFit.w,h:measuresToFit.h}}return true}function setStyle($el,style){var el=$el[0];if(el.styleSheet){el.styleSheet.cssText=style}else{$el.html(style)}}function findShadowEdge(pos,min,max,dir){return min===max?false:dir==="vertical"?pos<=min?"top":pos>=max?"bottom":"top bottom":pos<=min?"left":pos>=max?"right":"left right"}function smartClick($el,fn,_options){_options=_options||{};$el.each(function(){var $this=$(this),thisData=$this.data(),startEvent;if(thisData.clickOn)return;thisData.clickOn=true;$.extend(touch($this,{onStart:function(e){startEvent=e;(_options.onStart||noop).call(this,e)},onMove:_options.onMove||noop,onTouchEnd:_options.onTouchEnd||noop,onEnd:function(result){if(result.moved)return;fn.call(this,startEvent)}}),{noMove:true})})}function div(classes,child){return'<div class="'+classes+'">'+(child||"")+"</div>"}function cls(className){return"."+className}function createVideoFrame(videoItem){var frame='<iframe src="'+videoItem.p+videoItem.type+".com/embed/"+videoItem.id+'" frameborder="0" allowfullscreen></iframe>';return frame}function shuffle(array){var l=array.length;while(l){var i=Math.floor(Math.random()*l--);var t=array[l];array[l]=array[i];array[i]=t}return array}function clone(array){return Object.prototype.toString.call(array)=="[object Array]"&&$.map(array,function(frame){return $.extend({},frame)})}function lockScroll($el,left,top){$el.scrollLeft(left||0).scrollTop(top||0)}function optionsToLowerCase(options){if(options){var opts={};$.each(options,function(key,value){opts[key.toLowerCase()]=value});return opts}}function getRatio(_ratio){if(!_ratio)return;var ratio=+_ratio;if(!isNaN(ratio)){return ratio}else{ratio=_ratio.split("/");return+ratio[0]/+ratio[1]||undefined}}function addEvent(el,e,fn,bool){if(!e)return;el.addEventListener?el.addEventListener(e,fn,!!bool):el.attachEvent("on"+e,fn)}function validateRestrictions(position,restriction){if(position>restriction.max){position=restriction.max}else{if(position<restriction.min){position=restriction.min}}return position}function validateSlidePos(opt,navShaftTouchTail,guessIndex,offsetNav,$guessNavFrame,$navWrap,dir){var position,size,wrapSize;if(dir==="horizontal"){size=opt.thumbwidth;wrapSize=$navWrap.width()}else{size=opt.thumbheight;wrapSize=$navWrap.height()}if((size+opt.margin)*(guessIndex+1)>=wrapSize-offsetNav){if(dir==="horizontal"){position=-$guessNavFrame.position().left}else{position=-$guessNavFrame.position().top}}else{if((size+opt.margin)*guessIndex<=Math.abs(offsetNav)){if(dir==="horizontal"){position=-$guessNavFrame.position().left+wrapSize-(size+opt.margin)}else{position=-$guessNavFrame.position().top+wrapSize-(size+opt.margin)}}else{position=offsetNav}}position=validateRestrictions(position,navShaftTouchTail);return position||0}function elIsDisabled(el){return!!el.getAttribute("disabled")}function disableAttr(FLAG,disable){if(disable){return{disabled:FLAG}}else{return{tabindex:FLAG*-1+"",disabled:FLAG}}}function addEnterUp(el,fn){addEvent(el,"keyup",function(e){elIsDisabled(el)||e.keyCode==13&&fn.call(el,e)})}function addFocus(el,fn){addEvent(el,"focus",el.onfocusin=function(e){fn.call(el,e)},true)}function stopEvent(e,stopPropagation){e.preventDefault?e.preventDefault():e.returnValue=false;stopPropagation&&e.stopPropagation&&e.stopPropagation()}function stubEvent($el,eventType){var isIOS=/ip(ad|hone|od)/i.test(window.navigator.userAgent);if(isIOS&&eventType==="touchend"){$el.on("touchend",function(e){$DOCUMENT.trigger("mouseup",e)})}$el.on(eventType,function(e){stopEvent(e,true);return false})}function getDirectionSign(forward){return forward?">":"<"}var UTIL=function(){function setRatioClass($el,wh,ht){var rateImg=wh/ht;if(rateImg<=1){$el.parent().removeClass(horizontalImageClass);$el.parent().addClass(verticalImageClass)}else{$el.parent().removeClass(verticalImageClass);$el.parent().addClass(horizontalImageClass)}}function setThumbAttr($frame,value,searchAttr){var attr=searchAttr;if(!$frame.attr(attr)&&$frame.attr(attr)!==undefined){$frame.attr(attr,value)}if($frame.find("["+attr+"]").length){$frame.find("["+attr+"]").each(function(){$(this).attr(attr,value)})}}function isExpectedCaption(frameItem,isExpected,undefined){var expected=false,frameExpected;frameItem.showCaption===undefined||frameItem.showCaption===true?frameExpected=true:frameExpected=false;if(!isExpected){return false}if(frameItem.caption&&frameExpected){expected=true}return expected}return{setRatio:setRatioClass,setThumbAttr:setThumbAttr,isExpectedCaption:isExpectedCaption}}(UTIL||{},jQuery);function slide($el,options){var elData=$el.data(),elPos=Math.round(options.pos),onEndFn=function(){if(elData&&elData.sliding){elData.sliding=false}(options.onEnd||noop)()};if(typeof options.overPos!=="undefined"&&options.overPos!==options.pos){elPos=options.overPos}var translate=$.extend(getTranslate(elPos,options.direction),options.width&&{width:options.width},options.height&&{height:options.height});if(elData&&elData.sliding){elData.sliding=true}if(CSS3){$el.css($.extend(getDuration(options.time),translate));if(options.time>10){afterTransition($el,"transform",onEndFn,options.time)}else{onEndFn()}}else{$el.stop().animate(translate,options.time,BEZIER,onEndFn)}}function fade($el1,$el2,$frames,options,fadeStack,chain){var chainedFLAG=typeof chain!=="undefined";if(!chainedFLAG){fadeStack.push(arguments);Array.prototype.push.call(arguments,fadeStack.length);if(fadeStack.length>1)return}$el1=$el1||$($el1);$el2=$el2||$($el2);var _$el1=$el1[0],_$el2=$el2[0],crossfadeFLAG=options.method==="crossfade",onEndFn=function(){if(!onEndFn.done){onEndFn.done=true;var args=(chainedFLAG||fadeStack.shift())&&fadeStack.shift();args&&fade.apply(this,args);(options.onEnd||noop)(!!args)}},time=options.time/(chain||1);$frames.removeClass(fadeRearClass+" "+fadeFrontClass);$el1.stop().addClass(fadeRearClass);$el2.stop().addClass(fadeFrontClass);crossfadeFLAG&&_$el2&&$el1.fadeTo(0,0);$el1.fadeTo(crossfadeFLAG?time:0,1,crossfadeFLAG&&onEndFn);$el2.fadeTo(time,0,onEndFn);_$el1&&crossfadeFLAG||_$el2||onEndFn()}var lastEvent,moveEventType,preventEvent,preventEventTimeout,dragDomEl;function extendEvent(e){var touch=(e.touches||[])[0]||e;e._x=touch.pageX||touch.originalEvent.pageX;e._y=touch.clientY||touch.originalEvent.clientY;e._now=$.now()}function touch($el,options){var el=$el[0],tail={},touchEnabledFLAG,startEvent,$target,controlTouch,touchFLAG,targetIsSelectFLAG,targetIsLinkFlag,tolerance,moved;function onStart(e){$target=$(e.target);tail.checked=targetIsSelectFLAG=targetIsLinkFlag=moved=false;if(touchEnabledFLAG||tail.flow||e.touches&&e.touches.length>1||e.which>1||lastEvent&&lastEvent.type!==e.type&&preventEvent||(targetIsSelectFLAG=options.select&&$target.is(options.select,el)))return targetIsSelectFLAG;touchFLAG=e.type==="touchstart";targetIsLinkFlag=$target.is("a, a *",el);controlTouch=tail.control;tolerance=tail.noMove||tail.noSwipe||controlTouch?16:!tail.snap?4:0;extendEvent(e);startEvent=lastEvent=e;moveEventType=e.type.replace(/down|start/,"move").replace(/Down/,"Move");(options.onStart||noop).call(el,e,{control:controlTouch,$target:$target});touchEnabledFLAG=tail.flow=true;if(!touchFLAG||tail.go)stopEvent(e)}function onMove(e){if(e.touches&&e.touches.length>1||MS_POINTER&&!e.isPrimary||moveEventType!==e.type||!touchEnabledFLAG){touchEnabledFLAG&&onEnd();(options.onTouchEnd||noop)();return}extendEvent(e);var xDiff=Math.abs(e._x-startEvent._x),yDiff=Math.abs(e._y-startEvent._y),xyDiff=xDiff-yDiff,xWin=(tail.go||tail.x||xyDiff>=0)&&!tail.noSwipe,yWin=xyDiff<0;if(touchFLAG&&!tail.checked){if(touchEnabledFLAG=xWin){stopEvent(e)}}else{stopEvent(e);if(movedEnough(xDiff,yDiff)){(options.onMove||noop).call(el,e,{touch:touchFLAG})}}if(!moved&&movedEnough(xDiff,yDiff)&&Math.sqrt(Math.pow(xDiff,2)+Math.pow(yDiff,2))>tolerance){moved=true}tail.checked=tail.checked||xWin||yWin}function movedEnough(xDiff,yDiff){return xDiff>yDiff&&xDiff>1.5}function onEnd(e){(options.onTouchEnd||noop)();var _touchEnabledFLAG=touchEnabledFLAG;tail.control=touchEnabledFLAG=false;if(_touchEnabledFLAG){tail.flow=false}if(!_touchEnabledFLAG||targetIsLinkFlag&&!tail.checked)return;e&&stopEvent(e);preventEvent=true;clearTimeout(preventEventTimeout);preventEventTimeout=setTimeout(function(){preventEvent=false},1e3);(options.onEnd||noop).call(el,{moved:moved,$target:$target,control:controlTouch,touch:touchFLAG,startEvent:startEvent,aborted:!e||e.type==="MSPointerCancel"})}function onOtherStart(){if(tail.flow)return;tail.flow=true}function onOtherEnd(){if(!tail.flow)return;tail.flow=false}if(MS_POINTER){addEvent(el,"MSPointerDown",onStart);addEvent(document,"MSPointerMove",onMove);addEvent(document,"MSPointerCancel",onEnd);addEvent(document,"MSPointerUp",onEnd)}else{addEvent(el,"touchstart",onStart);addEvent(el,"touchmove",onMove);addEvent(el,"touchend",onEnd);addEvent(document,"touchstart",onOtherStart);addEvent(document,"touchend",onOtherEnd);addEvent(document,"touchcancel",onOtherEnd);$WINDOW.on("scroll",onOtherEnd);$el.on("mousedown pointerdown",onStart);$DOCUMENT.on("mousemove pointermove",onMove).on("mouseup pointerup",onEnd)}if(Modernizr.touch){dragDomEl="a"}else{dragDomEl="div"}$el.on("click",dragDomEl,function(e){tail.checked&&stopEvent(e)});return tail}function moveOnTouch($el,options){var el=$el[0],elData=$el.data(),tail={},startCoo,coo,startElPos,moveElPos,edge,moveTrack,startTime,endTime,min,max,snap,dir,slowFLAG,controlFLAG,moved,tracked;function startTracking(e,noStop){tracked=true;startCoo=coo=dir==="vertical"?e._y:e._x;startTime=e._now;moveTrack=[[startTime,startCoo]];startElPos=moveElPos=tail.noMove||noStop?0:stop($el,(options.getPos||noop)());(options.onStart||noop).call(el,e)}function onStart(e,result){min=tail.min;max=tail.max;snap=tail.snap,dir=tail.direction||"horizontal",$el.navdir=dir;slowFLAG=e.altKey;tracked=moved=false;controlFLAG=result.control;if(!controlFLAG&&!elData.sliding){startTracking(e)}}function onMove(e,result){if(!tail.noSwipe){if(!tracked){startTracking(e)}coo=dir==="vertical"?e._y:e._x;moveTrack.push([e._now,coo]);moveElPos=startElPos-(startCoo-coo);edge=findShadowEdge(moveElPos,min,max,dir);if(moveElPos<=min){moveElPos=edgeResistance(moveElPos,min)}else if(moveElPos>=max){moveElPos=edgeResistance(moveElPos,max)}if(!tail.noMove){$el.css(getTranslate(moveElPos,dir));if(!moved){moved=true;result.touch||MS_POINTER||$el.addClass(grabbingClass)}(options.onMove||noop).call(el,e,{pos:moveElPos,edge:edge})}}}function onEnd(result){if(tail.noSwipe&&result.moved)return;if(!tracked){startTracking(result.startEvent,true)}result.touch||MS_POINTER||$el.removeClass(grabbingClass);endTime=$.now();var _backTimeIdeal=endTime-TOUCH_TIMEOUT,_backTime,_timeDiff,_timeDiffLast,backTime=null,backCoo,virtualPos,limitPos,newPos,overPos,time=TRANSITION_DURATION,speed,friction=options.friction;for(var _i=moveTrack.length-1;_i>=0;_i--){_backTime=moveTrack[_i][0];_timeDiff=Math.abs(_backTime-_backTimeIdeal);if(backTime===null||_timeDiff<_timeDiffLast){backTime=_backTime;backCoo=moveTrack[_i][1]}else if(backTime===_backTimeIdeal||_timeDiff>_timeDiffLast){break}_timeDiffLast=_timeDiff}newPos=minMaxLimit(moveElPos,min,max);var cooDiff=backCoo-coo,forwardFLAG=cooDiff>=0,timeDiff=endTime-backTime,longTouchFLAG=timeDiff>TOUCH_TIMEOUT,swipeFLAG=!longTouchFLAG&&moveElPos!==startElPos&&newPos===moveElPos;if(snap){newPos=minMaxLimit(Math[swipeFLAG?forwardFLAG?"floor":"ceil":"round"](moveElPos/snap)*snap,min,max);min=max=newPos}if(swipeFLAG&&(snap||newPos===moveElPos)){speed=-(cooDiff/timeDiff);time*=minMaxLimit(Math.abs(speed),options.timeLow,options.timeHigh);virtualPos=Math.round(moveElPos+speed*time/friction);if(!snap){newPos=virtualPos}if(!forwardFLAG&&virtualPos>max||forwardFLAG&&virtualPos<min){limitPos=forwardFLAG?min:max;overPos=virtualPos-limitPos;if(!snap){newPos=limitPos}overPos=minMaxLimit(newPos+overPos*.03,limitPos-50,limitPos+50);time=Math.abs((moveElPos-overPos)/(speed/friction))}}time*=slowFLAG?10:1;(options.onEnd||noop).call(el,$.extend(result,{moved:result.moved||longTouchFLAG&&snap,pos:moveElPos,newPos:newPos,overPos:overPos,time:time,dir:dir}))}tail=$.extend(touch(options.$wrap,$.extend({},options,{onStart:onStart,onMove:onMove,onEnd:onEnd})),tail);return tail}function wheel($el,options){var el=$el[0],lockFLAG,lastDirection,lastNow,tail={prevent:{}};addEvent(el,WHEEL,function(e){var yDelta=e.wheelDeltaY||-1*e.deltaY||0,xDelta=e.wheelDeltaX||-1*e.deltaX||0,xWin=Math.abs(xDelta)&&!Math.abs(yDelta),direction=getDirectionSign(xDelta<0),sameDirection=lastDirection===direction,now=$.now(),tooFast=now-lastNow<TOUCH_TIMEOUT;lastDirection=direction;lastNow=now;if(!xWin||!tail.ok||tail.prevent[direction]&&!lockFLAG){return}else{stopEvent(e,true);if(lockFLAG&&sameDirection&&tooFast){return}}if(options.shift){lockFLAG=true;clearTimeout(tail.t);tail.t=setTimeout(function(){lockFLAG=false},SCROLL_LOCK_TIMEOUT)}(options.onEnd||noop)(e,options.shift?direction:xDelta)});return tail}jQuery.Fotorama=function($fotorama,opts){$HTML=$("html");$BODY=$("body");var that=this,stamp=$.now(),stampClass=_fotoramaClass+stamp,fotorama=$fotorama[0],data,dataFrameCount=1,fotoramaData=$fotorama.data(),size,$style=$("<style></style>"),$anchor=$(div(hiddenClass)),$wrap=$fotorama.find(cls(wrapClass)),$stage=$wrap.find(cls(stageClass)),stage=$stage[0],$stageShaft=$fotorama.find(cls(stageShaftClass)),$stageFrame=$(),$arrPrev=$fotorama.find(cls(arrPrevClass)),$arrNext=$fotorama.find(cls(arrNextClass)),$arrs=$fotorama.find(cls(arrClass)),$navWrap=$fotorama.find(cls(navWrapClass)),$nav=$navWrap.find(cls(navClass)),$navShaft=$nav.find(cls(navShaftClass)),$navFrame,$navDotFrame=$(),$navThumbFrame=$(),stageShaftData=$stageShaft.data(),navShaftData=$navShaft.data(),$thumbBorder=$fotorama.find(cls(thumbBorderClass)),$thumbArrLeft=$fotorama.find(cls(thumbArrLeft)),$thumbArrRight=$fotorama.find(cls(thumbArrRight)),$fullscreenIcon=$fotorama.find(cls(fullscreenIconClass)),fullscreenIcon=$fullscreenIcon[0],$videoPlay=$(div(videoPlayClass)),$videoClose=$fotorama.find(cls(videoCloseClass)),videoClose=$videoClose[0],$spinner=$fotorama.find(cls(fotoramaSpinnerClass)),$videoPlaying,activeIndex=false,activeFrame,activeIndexes,repositionIndex,dirtyIndex,lastActiveIndex,prevIndex,nextIndex,nextAutoplayIndex,startIndex,o_loop,o_nav,o_navThumbs,o_navTop,o_allowFullScreen,o_nativeFullScreen,o_fade,o_thumbSide,o_thumbSide2,o_transitionDuration,o_transition,o_shadows,o_rtl,o_keyboard,lastOptions={},measures={},measuresSetFLAG,stageShaftTouchTail={},stageWheelTail={},navShaftTouchTail={},navWheelTail={},scrollTop,scrollLeft,showedFLAG,pausedAutoplayFLAG,stoppedAutoplayFLAG,toDeactivate={},toDetach={},measuresStash,touchedFLAG,hoverFLAG,navFrameKey,stageLeft=0,fadeStack=[];$wrap[STAGE_FRAME_KEY]=$('<div class="'+stageFrameClass+'"></div>');$wrap[NAV_THUMB_FRAME_KEY]=$($.Fotorama.jst.thumb());$wrap[NAV_DOT_FRAME_KEY]=$($.Fotorama.jst.dots());toDeactivate[STAGE_FRAME_KEY]=[];toDeactivate[NAV_THUMB_FRAME_KEY]=[];toDeactivate[NAV_DOT_FRAME_KEY]=[];toDetach[STAGE_FRAME_KEY]={};$wrap.addClass(CSS3?wrapCss3Class:wrapCss2Class);fotoramaData.fotorama=this;function checkForVideo(){$.each(data,function(i,dataFrame){if(!dataFrame.i){dataFrame.i=dataFrameCount++;var video=findVideoId(dataFrame.video,true);if(video){var thumbs={};dataFrame.video=video;if(!dataFrame.img&&!dataFrame.thumb){thumbs=getVideoThumbs(dataFrame,data,that)}else{dataFrame.thumbsReady=true}updateData(data,{img:thumbs.img,thumb:thumbs.thumb},dataFrame.i,that)}}})}function allowKey(key){return o_keyboard[key]}function setStagePosition(){if($stage!==undefined){if(opts.navdir=="vertical"){var padding=opts.thumbwidth+opts.thumbmargin;$stage.css("left",padding);$arrNext.css("right",padding);$fullscreenIcon.css("right",padding);$wrap.css("width",$wrap.css("width")+padding);$stageShaft.css("max-width",$wrap.width()-padding)}else{$stage.css("left","");$arrNext.css("right","");$fullscreenIcon.css("right","");$wrap.css("width",$wrap.css("width")+padding);$stageShaft.css("max-width","")}}}function bindGlobalEvents(FLAG){var keydownCommon="keydown."+_fotoramaClass,localStamp=_fotoramaClass+stamp,keydownLocal="keydown."+localStamp,keyupLocal="keyup."+localStamp,resizeLocal="resize."+localStamp+" "+"orientationchange."+localStamp,showParams;if(FLAG){$DOCUMENT.on(keydownLocal,function(e){var catched,index;if($videoPlaying&&e.keyCode===27){catched=true;unloadVideo($videoPlaying,true,true)}else if(that.fullScreen||opts.keyboard&&!that.index){if(e.keyCode===27){catched=true;that.cancelFullScreen()}else if(e.shiftKey&&e.keyCode===32&&allowKey("space")||!e.altKey&&!e.metaKey&&e.keyCode===37&&allowKey("left")||e.keyCode===38&&allowKey("up")&&$(":focus").attr("data-gallery-role")){that.longPress.progress();index="<"}else if(e.keyCode===32&&allowKey("space")||!e.altKey&&!e.metaKey&&e.keyCode===39&&allowKey("right")||e.keyCode===40&&allowKey("down")&&$(":focus").attr("data-gallery-role")){that.longPress.progress();index=">"}else if(e.keyCode===36&&allowKey("home")){that.longPress.progress();index="<<"}else if(e.keyCode===35&&allowKey("end")){that.longPress.progress();index=">>"}}(catched||index)&&stopEvent(e);showParams={index:index,slow:e.altKey,user:true};index&&(that.longPress.inProgress?that.showWhileLongPress(showParams):that.show(showParams))});if(FLAG){$DOCUMENT.on(keyupLocal,function(e){if(that.longPress.inProgress){that.showEndLongPress({user:true})}that.longPress.reset()})}if(!that.index){$DOCUMENT.off(keydownCommon).on(keydownCommon,"textarea, input, select",function(e){!$BODY.hasClass(_fullscreenClass)&&e.stopPropagation()})}$WINDOW.on(resizeLocal,that.resize)}else{$DOCUMENT.off(keydownLocal);$WINDOW.off(resizeLocal)}}function appendElements(FLAG){if(FLAG===appendElements.f)return;if(FLAG){$fotorama.addClass(_fotoramaClass+" "+stampClass).before($anchor).before($style);addInstance(that)}else{$anchor.detach();$style.detach();$fotorama.html(fotoramaData.urtext).removeClass(stampClass);hideInstance(that)}bindGlobalEvents(FLAG);appendElements.f=FLAG}function setData(){data=that.data=data||clone(opts.data)||getDataFromHtml($fotorama);size=that.size=data.length;ready.ok&&opts.shuffle&&shuffle(data);checkForVideo();activeIndex=limitIndex(activeIndex);size&&appendElements(true)}function stageNoMove(){var _noMove=size<2||$videoPlaying;stageShaftTouchTail.noMove=_noMove||o_fade;stageShaftTouchTail.noSwipe=_noMove||!opts.swipe;!o_transition&&$stageShaft.toggleClass(grabClass,!opts.click&&!stageShaftTouchTail.noMove&&!stageShaftTouchTail.noSwipe);MS_POINTER&&$wrap.toggleClass(wrapPanYClass,!stageShaftTouchTail.noSwipe)}function setAutoplayInterval(interval){if(interval===true)interval="";opts.autoplay=Math.max(+interval||AUTOPLAY_INTERVAL,o_transitionDuration*1.5)}function updateThumbArrow(opt){if(opt.navarrows&&opt.nav==="thumbs"){$thumbArrLeft.show();$thumbArrRight.show()}else{$thumbArrLeft.hide();$thumbArrRight.hide()}}function getThumbsInSlide($el,opts){return Math.floor($wrap.width()/(opts.thumbwidth+opts.thumbmargin))}function setOptions(){if(!opts.nav||opts.nav==="dots"){opts.navdir="horizontal"}that.options=opts=optionsToLowerCase(opts);thumbsPerSlide=getThumbsInSlide($wrap,opts);o_fade=opts.transition==="crossfade"||opts.transition==="dissolve";o_loop=opts.loop&&(size>2||o_fade&&(!o_transition||o_transition!=="slide"));o_transitionDuration=+opts.transitionduration||TRANSITION_DURATION;o_rtl=opts.direction==="rtl";o_keyboard=$.extend({},opts.keyboard&&KEYBOARD_OPTIONS,opts.keyboard);updateThumbArrow(opts);var classes={add:[],remove:[]};function addOrRemoveClass(FLAG,value){classes[FLAG?"add":"remove"].push(value)}if(size>1){o_nav=opts.nav;o_navTop=opts.navposition==="top";classes.remove.push(selectClass);$arrs.toggle(!!opts.arrows)}else{o_nav=false;$arrs.hide()}arrsUpdate();stageWheelUpdate();thumbArrUpdate();if(opts.autoplay)setAutoplayInterval(opts.autoplay);o_thumbSide=numberFromMeasure(opts.thumbwidth)||THUMB_SIZE;o_thumbSide2=numberFromMeasure(opts.thumbheight)||THUMB_SIZE;stageWheelTail.ok=navWheelTail.ok=opts.trackpad&&!SLOW;stageNoMove();extendMeasures(opts,[measures]);o_navThumbs=o_nav==="thumbs";if($navWrap.filter(":hidden")&&!!o_nav){$navWrap.show()}if(o_navThumbs){frameDraw(size,"navThumb");$navFrame=$navThumbFrame;navFrameKey=NAV_THUMB_FRAME_KEY;setStyle($style,$.Fotorama.jst.style({w:o_thumbSide,h:o_thumbSide2,b:opts.thumbborderwidth,m:opts.thumbmargin,s:stamp,q:!COMPAT}));$nav.addClass(navThumbsClass).removeClass(navDotsClass)}else if(o_nav==="dots"){frameDraw(size,"navDot");$navFrame=$navDotFrame;navFrameKey=NAV_DOT_FRAME_KEY;$nav.addClass(navDotsClass).removeClass(navThumbsClass)}else{$navWrap.hide();o_nav=false;$nav.removeClass(navThumbsClass+" "+navDotsClass)}if(o_nav){if(o_navTop){$navWrap.insertBefore($stage)}else{$navWrap.insertAfter($stage)}frameAppend.nav=false;frameAppend($navFrame,$navShaft,"nav")}o_allowFullScreen=opts.allowfullscreen;if(o_allowFullScreen){$fullscreenIcon.prependTo($stage);o_nativeFullScreen=FULLSCREEN&&o_allowFullScreen==="native";stubEvent($fullscreenIcon,"touchend")}else{$fullscreenIcon.detach();o_nativeFullScreen=false}addOrRemoveClass(o_fade,wrapFadeClass);addOrRemoveClass(!o_fade,wrapSlideClass);addOrRemoveClass(!opts.captions,wrapNoCaptionsClass);addOrRemoveClass(o_rtl,wrapRtlClass);addOrRemoveClass(opts.arrows,wrapToggleArrowsClass);o_shadows=opts.shadows&&!SLOW;addOrRemoveClass(!o_shadows,wrapNoShadowsClass);$wrap.addClass(classes.add.join(" ")).removeClass(classes.remove.join(" "));lastOptions=$.extend({},opts);setStagePosition()}function normalizeIndex(index){return index<0?(size+index%size)%size:index>=size?index%size:index}function limitIndex(index){return minMaxLimit(index,0,size-1)}function edgeIndex(index){return o_loop?normalizeIndex(index):limitIndex(index)}function getPrevIndex(index){return index>0||o_loop?index-1:false}function getNextIndex(index){return index<size-1||o_loop?index+1:false}function setStageShaftMinmaxAndSnap(){stageShaftTouchTail.min=o_loop?-Infinity:-getPosByIndex(size-1,measures.w,opts.margin,repositionIndex);stageShaftTouchTail.max=o_loop?Infinity:-getPosByIndex(0,measures.w,opts.margin,repositionIndex);stageShaftTouchTail.snap=measures.w+opts.margin}function setNavShaftMinMax(){var isVerticalDir=opts.navdir==="vertical";var param=isVerticalDir?$navShaft.height():$navShaft.width();var mainParam=isVerticalDir?measures.h:measures.nw;navShaftTouchTail.min=Math.min(0,mainParam-param);navShaftTouchTail.max=0;navShaftTouchTail.direction=opts.navdir;$navShaft.toggleClass(grabClass,!(navShaftTouchTail.noMove=navShaftTouchTail.min===navShaftTouchTail.max))}function eachIndex(indexes,type,fn){if(typeof indexes==="number"){indexes=new Array(indexes);var rangeFLAG=true}return $.each(indexes,function(i,index){if(rangeFLAG)index=i;if(typeof index==="number"){var dataFrame=data[normalizeIndex(index)];if(dataFrame){var key="$"+type+"Frame",$frame=dataFrame[key];fn.call(this,i,index,dataFrame,$frame,key,$frame&&$frame.data())}}})}function setMeasures(width,height,ratio,index){if(!measuresSetFLAG||measuresSetFLAG==="*"&&index===startIndex){width=measureIsValid(opts.width)||measureIsValid(width)||WIDTH;height=measureIsValid(opts.height)||measureIsValid(height)||HEIGHT;that.resize({width:width,ratio:opts.ratio||ratio||width/height},0,index!==startIndex&&"*")}}function loadImg(indexes,type,specialMeasures,again){eachIndex(indexes,type,function(i,index,dataFrame,$frame,key,frameData){if(!$frame)return;var fullFLAG=that.fullScreen&&!frameData.$full&&type==="stage";if(frameData.$img&&!again&&!fullFLAG)return;var img=new Image,$img=$(img),imgData=$img.data();frameData[fullFLAG?"$full":"$img"]=$img;var srcKey=type==="stage"?fullFLAG?"full":"img":"thumb",src=dataFrame[srcKey],dummy=fullFLAG?dataFrame["img"]:dataFrame[type==="stage"?"thumb":"img"];if(type==="navThumb")$frame=frameData.$wrap;function triggerTriggerEvent(event){var _index=normalizeIndex(index);triggerEvent(event,{index:_index,src:src,frame:data[_index]})}function error(){$img.remove();$.Fotorama.cache[src]="error";if((!dataFrame.html||type!=="stage")&&dummy&&dummy!==src){dataFrame[srcKey]=src=dummy;frameData.$full=null;loadImg([index],type,specialMeasures,true)}else{if(src&&!dataFrame.html&&!fullFLAG){$frame.trigger("f:error").removeClass(loadingClass).addClass(errorClass);triggerTriggerEvent("error")}else if(type==="stage"){$frame.trigger("f:load").removeClass(loadingClass+" "+errorClass).addClass(loadedClass);triggerTriggerEvent("load");setMeasures()}frameData.state="error";if(size>1&&data[index]===dataFrame&&!dataFrame.html&&!dataFrame.deleted&&!dataFrame.video&&!fullFLAG){dataFrame.deleted=true;that.splice(index,1)}}}function loaded(){$.Fotorama.measures[src]=imgData.measures=$.Fotorama.measures[src]||{width:img.width,height:img.height,ratio:img.width/img.height};setMeasures(imgData.measures.width,imgData.measures.height,imgData.measures.ratio,index);$img.off("load error").addClass(""+(fullFLAG?imgFullClass:imgClass)).attr("aria-hidden","false").prependTo($frame);if($frame.hasClass(stageFrameClass)&&!$frame.hasClass(videoContainerClass)){$frame.attr("href",$img.attr("src"))}fit($img,($.isFunction(specialMeasures)?specialMeasures():specialMeasures)||measures);$.Fotorama.cache[src]=frameData.state="loaded";setTimeout(function(){$frame.trigger("f:load").removeClass(loadingClass+" "+errorClass).addClass(loadedClass+" "+(fullFLAG?loadedFullClass:loadedImgClass));if(type==="stage"){triggerTriggerEvent("load")}else if(dataFrame.thumbratio===AUTO||!dataFrame.thumbratio&&opts.thumbratio===AUTO){dataFrame.thumbratio=imgData.measures.ratio;reset()}},0)}if(!src){error();return}function waitAndLoad(){var _i=10;waitFor(function(){return!touchedFLAG||!_i--&&!SLOW},function(){loaded()})}if(!$.Fotorama.cache[src]){$.Fotorama.cache[src]="*";$img.on("load",waitAndLoad).on("error",error)}else{(function justWait(){if($.Fotorama.cache[src]==="error"){error()}else if($.Fotorama.cache[src]==="loaded"){setTimeout(waitAndLoad,0)}else{setTimeout(justWait,100)}})()}frameData.state="";img.src=src;if(frameData.data.caption){img.alt=frameData.data.caption||""}if(frameData.data.full){$(img).data("original",frameData.data.full)}if(UTIL.isExpectedCaption(dataFrame,opts.showcaption)){$(img).attr("aria-labelledby",dataFrame.labelledby)}})}function updateFotoramaState(){var $frame=activeFrame[STAGE_FRAME_KEY];if($frame&&!$frame.data().state){$spinner.addClass(spinnerShowClass);$frame.on("f:load f:error",function(){$frame.off("f:load f:error");$spinner.removeClass(spinnerShowClass)})}}function addNavFrameEvents(frame){addEnterUp(frame,onNavFrameClick);addFocus(frame,function(){setTimeout(function(){lockScroll($nav)},0);slideNavShaft({time:o_transitionDuration,guessIndex:$(this).data().eq,minMax:navShaftTouchTail})})}function frameDraw(indexes,type){eachIndex(indexes,type,function(i,index,dataFrame,$frame,key,frameData){if($frame)return;$frame=dataFrame[key]=$wrap[key].clone();frameData=$frame.data();frameData.data=dataFrame;var frame=$frame[0],labelledbyValue="labelledby"+$.now();if(type==="stage"){if(dataFrame.html){$('<div class="'+htmlClass+'"></div>').append(dataFrame._html?$(dataFrame.html).removeAttr("id").html(dataFrame._html):dataFrame.html).appendTo($frame)}if(dataFrame.id){labelledbyValue=dataFrame.id||labelledbyValue}dataFrame.labelledby=labelledbyValue;if(UTIL.isExpectedCaption(dataFrame,opts.showcaption)){$($.Fotorama.jst.frameCaption({caption:dataFrame.caption,labelledby:labelledbyValue})).appendTo($frame)}dataFrame.video&&$frame.addClass(stageFrameVideoClass).append($videoPlay.clone());addFocus(frame,function(){setTimeout(function(){lockScroll($stage)},0);clickToShow({index:frameData.eq,user:true})});$stageFrame=$stageFrame.add($frame)}else if(type==="navDot"){addNavFrameEvents(frame);$navDotFrame=$navDotFrame.add($frame)}else if(type==="navThumb"){addNavFrameEvents(frame);frameData.$wrap=$frame.children(":first");$navThumbFrame=$navThumbFrame.add($frame);if(dataFrame.video){frameData.$wrap.append($videoPlay.clone())}}})}function callFit($img,measuresToFit){return $img&&$img.length&&fit($img,measuresToFit)}function stageFramePosition(indexes){eachIndex(indexes,"stage",function(i,index,dataFrame,$frame,key,frameData){if(!$frame)return;var normalizedIndex=normalizeIndex(index);frameData.eq=normalizedIndex;toDetach[STAGE_FRAME_KEY][normalizedIndex]=$frame.css($.extend({left:o_fade?0:getPosByIndex(index,measures.w,opts.margin,repositionIndex)},o_fade&&getDuration(0)));if(isDetached($frame[0])){$frame.appendTo($stageShaft);unloadVideo(dataFrame.$video)}callFit(frameData.$img,measures);callFit(frameData.$full,measures);if($frame.hasClass(stageFrameClass)&&!($frame.attr("aria-hidden")==="false"&&$frame.hasClass(activeClass))){$frame.attr("aria-hidden","true")}})}function thumbsDraw(pos,loadFLAG){var leftLimit,rightLimit,exceedLimit;if(o_nav!=="thumbs"||isNaN(pos))return;leftLimit=-pos;rightLimit=-pos+measures.nw;if(opts.navdir==="vertical"){pos=pos-opts.thumbheight;rightLimit=-pos+measures.h}$navThumbFrame.each(function(){var $this=$(this),thisData=$this.data(),eq=thisData.eq,getSpecialMeasures=function(){return{h:o_thumbSide2,w:thisData.w}},specialMeasures=getSpecialMeasures(),exceedLimit=opts.navdir==="vertical"?thisData.t>rightLimit:thisData.l>rightLimit;specialMeasures.w=thisData.w;if(thisData.l+thisData.w<leftLimit||exceedLimit||callFit(thisData.$img,specialMeasures))return;loadFLAG&&loadImg([eq],"navThumb",getSpecialMeasures)})}function frameAppend($frames,$shaft,type){if(!frameAppend[type]){var thumbsFLAG=type==="nav"&&o_navThumbs,left=0,top=0;$shaft.append($frames.filter(function(){var actual,$this=$(this),frameData=$this.data();for(var _i=0,_l=data.length;_i<_l;_i++){if(frameData.data===data[_i]){actual=true;frameData.eq=_i;break}}return actual||$this.remove()&&false}).sort(function(a,b){return $(a).data().eq-$(b).data().eq}).each(function(){var $this=$(this),frameData=$this.data();UTIL.setThumbAttr($this,frameData.data.caption,"aria-label")}).each(function(){if(!thumbsFLAG)return;var $this=$(this),frameData=$this.data(),thumbwidth=Math.round(o_thumbSide2*frameData.data.thumbratio)||o_thumbSide,thumbheight=Math.round(o_thumbSide/frameData.data.thumbratio)||o_thumbSide2;frameData.t=top;frameData.h=thumbheight;frameData.l=left;frameData.w=thumbwidth;$this.css({width:thumbwidth});top+=thumbheight+opts.thumbmargin;left+=thumbwidth+opts.thumbmargin}));frameAppend[type]=true}}function getDirection(x){return x-stageLeft>measures.w/3}function disableDirrection(i){return!o_loop&&(!(activeIndex+i)||!(activeIndex-size+i))&&!$videoPlaying}function arrsUpdate(){var disablePrev=disableDirrection(0),disableNext=disableDirrection(1);$arrPrev.toggleClass(arrDisabledClass,disablePrev).attr(disableAttr(disablePrev,false));$arrNext.toggleClass(arrDisabledClass,disableNext).attr(disableAttr(disableNext,false))}function thumbArrUpdate(){var isLeftDisable=false,isRightDisable=false;if(opts.navtype==="thumbs"&&!opts.loop){activeIndex==0?isLeftDisable=true:isLeftDisable=false;activeIndex==opts.data.length-1?isRightDisable=true:isRightDisable=false}if(opts.navtype==="slides"){var pos=readPosition($navShaft,opts.navdir);pos>=navShaftTouchTail.max?isLeftDisable=true:isLeftDisable=false;pos<=navShaftTouchTail.min?isRightDisable=true:isRightDisable=false}$thumbArrLeft.toggleClass(arrDisabledClass,isLeftDisable).attr(disableAttr(isLeftDisable,true));$thumbArrRight.toggleClass(arrDisabledClass,isRightDisable).attr(disableAttr(isRightDisable,true))}function stageWheelUpdate(){if(stageWheelTail.ok){stageWheelTail.prevent={"<":disableDirrection(0),">":disableDirrection(1)}}}function getNavFrameBounds($navFrame){var navFrameData=$navFrame.data(),left,top,width,height;if(o_navThumbs){left=navFrameData.l;top=navFrameData.t;width=navFrameData.w;height=navFrameData.h}else{left=$navFrame.position().left;width=$navFrame.width()}var horizontalBounds={c:left+width/2,min:-left+opts.thumbmargin*10,max:-left+measures.w-width-opts.thumbmargin*10};var verticalBounds={c:top+height/2,min:-top+opts.thumbmargin*10,max:-top+measures.h-height-opts.thumbmargin*10};return opts.navdir==="vertical"?verticalBounds:horizontalBounds}function slideThumbBorder(time){var navFrameData=activeFrame[navFrameKey].data();slide($thumbBorder,{time:time*1.2,pos:opts.navdir==="vertical"?navFrameData.t:navFrameData.l,width:navFrameData.w,height:navFrameData.h,direction:opts.navdir})}function slideNavShaft(options){var $guessNavFrame=data[options.guessIndex][navFrameKey],typeOfAnimation=opts.navtype;var overflowFLAG,time,minMax,boundTop,boundLeft,l,pos,x;if($guessNavFrame){if(typeOfAnimation==="thumbs"){overflowFLAG=navShaftTouchTail.min!==navShaftTouchTail.max;minMax=options.minMax||overflowFLAG&&getNavFrameBounds(activeFrame[navFrameKey]);boundTop=overflowFLAG&&(options.keep&&slideNavShaft.t?slideNavShaft.l:minMaxLimit((options.coo||measures.nw/2)-getNavFrameBounds($guessNavFrame).c,minMax.min,minMax.max));boundLeft=overflowFLAG&&(options.keep&&slideNavShaft.l?slideNavShaft.l:minMaxLimit((options.coo||measures.nw/2)-getNavFrameBounds($guessNavFrame).c,minMax.min,minMax.max));l=opts.navdir==="vertical"?boundTop:boundLeft;pos=overflowFLAG&&minMaxLimit(l,navShaftTouchTail.min,navShaftTouchTail.max)||0;time=options.time*1.1;slide($navShaft,{time:time,pos:pos,direction:opts.navdir,onEnd:function(){thumbsDraw(pos,true);thumbArrUpdate()}});setShadow($nav,findShadowEdge(pos,navShaftTouchTail.min,navShaftTouchTail.max,opts.navdir));slideNavShaft.l=l}else{x=readPosition($navShaft,opts.navdir);time=options.time*1.11;pos=validateSlidePos(opts,navShaftTouchTail,options.guessIndex,x,$guessNavFrame,$navWrap,opts.navdir);slide($navShaft,{time:time,pos:pos,direction:opts.navdir,onEnd:function(){thumbsDraw(pos,true);thumbArrUpdate()}});setShadow($nav,findShadowEdge(pos,navShaftTouchTail.min,navShaftTouchTail.max,opts.navdir))}}}function navUpdate(){deactivateFrames(navFrameKey);toDeactivate[navFrameKey].push(activeFrame[navFrameKey].addClass(activeClass).attr("data-active",true))}function deactivateFrames(key){var _toDeactivate=toDeactivate[key];while(_toDeactivate.length){_toDeactivate.shift().removeClass(activeClass).attr("data-active",false)}}function detachFrames(key){var _toDetach=toDetach[key];$.each(activeIndexes,function(i,index){delete _toDetach[normalizeIndex(index)]});$.each(_toDetach,function(index,$frame){delete _toDetach[index];$frame.detach()})}function stageShaftReposition(skipOnEnd){repositionIndex=dirtyIndex=activeIndex;var $frame=activeFrame[STAGE_FRAME_KEY];if($frame){deactivateFrames(STAGE_FRAME_KEY);toDeactivate[STAGE_FRAME_KEY].push($frame.addClass(activeClass).attr("data-active",true));if($frame.hasClass(stageFrameClass)){$frame.attr("aria-hidden","false")}skipOnEnd||that.showStage.onEnd(true);stop($stageShaft,0,true);detachFrames(STAGE_FRAME_KEY);stageFramePosition(activeIndexes);setStageShaftMinmaxAndSnap();setNavShaftMinMax();addEnterUp($stageShaft[0],function(){if(!$fotorama.hasClass(fullscreenClass)){that.requestFullScreen();$fullscreenIcon.focus()}})}}function extendMeasures(options,measuresArray){if(!options)return;$.each(measuresArray,function(i,measures){if(!measures)return;$.extend(measures,{width:options.width||measures.width,height:options.height,minwidth:options.minwidth,maxwidth:options.maxwidth,minheight:options.minheight,maxheight:options.maxheight,ratio:getRatio(options.ratio)})})}function triggerEvent(event,extra){$fotorama.trigger(_fotoramaClass+":"+event,[that,extra])}function onTouchStart(){clearTimeout(onTouchEnd.t);touchedFLAG=1;if(opts.stopautoplayontouch){that.stopAutoplay()}else{pausedAutoplayFLAG=true}}function onTouchEnd(){if(!touchedFLAG)return;if(!opts.stopautoplayontouch){releaseAutoplay();changeAutoplay()}onTouchEnd.t=setTimeout(function(){touchedFLAG=0},TRANSITION_DURATION+TOUCH_TIMEOUT)}function releaseAutoplay(){pausedAutoplayFLAG=!!($videoPlaying||stoppedAutoplayFLAG)}function changeAutoplay(){clearTimeout(changeAutoplay.t);waitFor.stop(changeAutoplay.w);if(!opts.autoplay||pausedAutoplayFLAG){if(that.autoplay){that.autoplay=false;triggerEvent("stopautoplay")}return}if(!that.autoplay){that.autoplay=true;triggerEvent("startautoplay")}var _activeIndex=activeIndex;var frameData=activeFrame[STAGE_FRAME_KEY].data();changeAutoplay.w=waitFor(function(){return frameData.state||_activeIndex!==activeIndex},function(){changeAutoplay.t=setTimeout(function(){if(pausedAutoplayFLAG||_activeIndex!==activeIndex)return;var _nextAutoplayIndex=nextAutoplayIndex,nextFrameData=data[_nextAutoplayIndex][STAGE_FRAME_KEY].data();changeAutoplay.w=waitFor(function(){return nextFrameData.state||_nextAutoplayIndex!==nextAutoplayIndex},function(){if(pausedAutoplayFLAG||_nextAutoplayIndex!==nextAutoplayIndex)return;that.show(o_loop?getDirectionSign(!o_rtl):nextAutoplayIndex)})},opts.autoplay)})}that.startAutoplay=function(interval){if(that.autoplay)return this;pausedAutoplayFLAG=stoppedAutoplayFLAG=false;setAutoplayInterval(interval||opts.autoplay);changeAutoplay();return this};that.stopAutoplay=function(){if(that.autoplay){pausedAutoplayFLAG=stoppedAutoplayFLAG=true;changeAutoplay()}return this};that.showSlide=function(slideDir){var currentPosition=readPosition($navShaft,opts.navdir),pos,time=500*1.1,size=opts.navdir==="horizontal"?opts.thumbwidth:opts.thumbheight,onEnd=function(){thumbArrUpdate()};if(slideDir==="next"){pos=currentPosition-(size+opts.margin)*thumbsPerSlide}if(slideDir==="prev"){pos=currentPosition+(size+opts.margin)*thumbsPerSlide}pos=validateRestrictions(pos,navShaftTouchTail);thumbsDraw(pos,true);slide($navShaft,{time:time,pos:pos,direction:opts.navdir,onEnd:onEnd})};that.showWhileLongPress=function(options){if(that.longPress.singlePressInProgress){return}var index=calcActiveIndex(options);calcGlobalIndexes(index);var time=calcTime(options)/50;var _activeFrame=activeFrame;that.activeFrame=activeFrame=data[activeIndex];var silent=_activeFrame===activeFrame&&!options.user;that.showNav(silent,options,time);return this};that.showEndLongPress=function(options){if(that.longPress.singlePressInProgress){return}var index=calcActiveIndex(options);calcGlobalIndexes(index);var time=calcTime(options)/50;var _activeFrame=activeFrame;that.activeFrame=activeFrame=data[activeIndex];var silent=_activeFrame===activeFrame&&!options.user;that.showStage(silent,options,time);showedFLAG=typeof lastActiveIndex!=="undefined"&&lastActiveIndex!==activeIndex;lastActiveIndex=activeIndex;return this};function calcActiveIndex(options){var index;if(typeof options!=="object"){index=options;options={}}else{index=options.index}index=index===">"?dirtyIndex+1:index==="<"?dirtyIndex-1:index==="<<"?0:index===">>"?size-1:index;index=isNaN(index)?undefined:index;index=typeof index==="undefined"?activeIndex||0:index;return index}function calcGlobalIndexes(index){that.activeIndex=activeIndex=edgeIndex(index);prevIndex=getPrevIndex(activeIndex);nextIndex=getNextIndex(activeIndex);nextAutoplayIndex=normalizeIndex(activeIndex+(o_rtl?-1:1));activeIndexes=[activeIndex,prevIndex,nextIndex];dirtyIndex=o_loop?index:activeIndex}function calcTime(options){var diffIndex=Math.abs(lastActiveIndex-dirtyIndex),time=getNumber(options.time,function(){return Math.min(o_transitionDuration*(1+(diffIndex-1)/12),o_transitionDuration*2)});if(options.slow){time*=10}return time}that.showStage=function(silent,options,time){unloadVideo($videoPlaying,activeFrame.i!==data[normalizeIndex(repositionIndex)].i);frameDraw(activeIndexes,"stage");stageFramePosition(SLOW?[dirtyIndex]:[dirtyIndex,getPrevIndex(dirtyIndex),getNextIndex(dirtyIndex)]);updateTouchTails("go",true);silent||triggerEvent("show",{user:options.user,time:time});pausedAutoplayFLAG=true;var overPos=options.overPos;var onEnd=that.showStage.onEnd=function(skipReposition){if(onEnd.ok)return;onEnd.ok=true;skipReposition||stageShaftReposition(true);if(!silent){triggerEvent("showend",{user:options.user})}if(!skipReposition&&o_transition&&o_transition!==opts.transition){that.setOptions({transition:o_transition});o_transition=false;return}updateFotoramaState();loadImg(activeIndexes,"stage");updateTouchTails("go",false);stageWheelUpdate();stageCursor();releaseAutoplay();changeAutoplay();if(that.fullScreen){activeFrame[STAGE_FRAME_KEY].find("."+imgFullClass).attr("aria-hidden",false);activeFrame[STAGE_FRAME_KEY].find("."+imgClass).attr("aria-hidden",true)}else{activeFrame[STAGE_FRAME_KEY].find("."+imgFullClass).attr("aria-hidden",true);activeFrame[STAGE_FRAME_KEY].find("."+imgClass).attr("aria-hidden",false)}};if(!o_fade){slide($stageShaft,{pos:-getPosByIndex(dirtyIndex,measures.w,opts.margin,repositionIndex),overPos:overPos,time:time,onEnd:onEnd})}else{var $activeFrame=activeFrame[STAGE_FRAME_KEY],$prevActiveFrame=data[lastActiveIndex]&&activeIndex!==lastActiveIndex?data[lastActiveIndex][STAGE_FRAME_KEY]:null;fade($activeFrame,$prevActiveFrame,$stageFrame,{time:time,method:opts.transition,onEnd:onEnd},fadeStack)}arrsUpdate()};that.showNav=function(silent,options,time){thumbArrUpdate();if(o_nav){navUpdate();var guessIndex=limitIndex(activeIndex+minMaxLimit(dirtyIndex-lastActiveIndex,-1,1));slideNavShaft({time:time,coo:guessIndex!==activeIndex&&options.coo,guessIndex:typeof options.coo!=="undefined"?guessIndex:activeIndex,keep:silent});if(o_navThumbs)slideThumbBorder(time)}};that.show=function(options){that.longPress.singlePressInProgress=true;var index=calcActiveIndex(options);calcGlobalIndexes(index);var time=calcTime(options);var _activeFrame=activeFrame;that.activeFrame=activeFrame=data[activeIndex];var silent=_activeFrame===activeFrame&&!options.user;that.showStage(silent,options,time);that.showNav(silent,options,time);showedFLAG=typeof lastActiveIndex!=="undefined"&&lastActiveIndex!==activeIndex;lastActiveIndex=activeIndex;that.longPress.singlePressInProgress=false;return this};that.requestFullScreen=function(){if(o_allowFullScreen&&!that.fullScreen){var isVideo=$((that.activeFrame||{}).$stageFrame||{}).hasClass("fotorama-video-container");if(isVideo){return}scrollTop=$WINDOW.scrollTop();scrollLeft=$WINDOW.scrollLeft();lockScroll($WINDOW);updateTouchTails("x",true);measuresStash=$.extend({},measures);$fotorama.addClass(fullscreenClass).appendTo($BODY.addClass(_fullscreenClass));$HTML.addClass(_fullscreenClass);unloadVideo($videoPlaying,true,true);that.fullScreen=true;if(o_nativeFullScreen){fullScreenApi.request(fotorama)}that.resize();loadImg(activeIndexes,"stage");updateFotoramaState();triggerEvent("fullscreenenter");if(!("ontouchstart"in window)){$fullscreenIcon.focus()}}return this};function cancelFullScreen(){if(that.fullScreen){that.fullScreen=false;if(FULLSCREEN){fullScreenApi.cancel(fotorama)}$BODY.removeClass(_fullscreenClass);$HTML.removeClass(_fullscreenClass);$fotorama.removeClass(fullscreenClass).insertAfter($anchor);measures=$.extend({},measuresStash);unloadVideo($videoPlaying,true,true);updateTouchTails("x",false);that.resize();loadImg(activeIndexes,"stage");lockScroll($WINDOW,scrollLeft,scrollTop);triggerEvent("fullscreenexit")}}that.cancelFullScreen=function(){if(o_nativeFullScreen&&fullScreenApi.is()){fullScreenApi.cancel(document)}else{cancelFullScreen()}return this};that.toggleFullScreen=function(){return that[(that.fullScreen?"cancel":"request")+"FullScreen"]()};that.resize=function(options){if(!data)return this;var time=arguments[1]||0,setFLAG=arguments[2];thumbsPerSlide=getThumbsInSlide($wrap,opts);extendMeasures(!that.fullScreen?optionsToLowerCase(options):{width:$(window).width(),maxwidth:null,minwidth:null,height:$(window).height(),maxheight:null,minheight:null},[measures,setFLAG||that.fullScreen||opts]);var width=measures.width,height=measures.height,ratio=measures.ratio,windowHeight=$WINDOW.height()-(o_nav?$nav.height():0);if(measureIsValid(width)){$wrap.css({width:""});$wrap.css({height:""});$stage.css({width:""});$stage.css({height:""});$stageShaft.css({width:""});$stageShaft.css({height:""});$nav.css({width:""});$nav.css({height:""});$wrap.css({minWidth:measures.minwidth||0,maxWidth:measures.maxwidth||MAX_WIDTH});if(o_nav==="dots"){$navWrap.hide()}width=measures.W=measures.w=$wrap.width();measures.nw=o_nav&&numberFromWhatever(opts.navwidth,width)||width;$stageShaft.css({width:measures.w,marginLeft:(measures.W-measures.w)/2});height=numberFromWhatever(height,windowHeight);height=height||ratio&&width/ratio;if(height){width=Math.round(width);height=measures.h=Math.round(minMaxLimit(height,numberFromWhatever(measures.minheight,windowHeight),numberFromWhatever(measures.maxheight,windowHeight)));$stage.css({width:width,height:height});if(opts.navdir==="vertical"&&!that.fullscreen){$nav.width(opts.thumbwidth+opts.thumbmargin*2)}if(opts.navdir==="horizontal"&&!that.fullscreen){$nav.height(opts.thumbheight+opts.thumbmargin*2)}if(o_nav==="dots"){$nav.width(width).height("auto");$navWrap.show()}if(opts.navdir==="vertical"&&that.fullScreen){$stage.css("height",$WINDOW.height())}if(opts.navdir==="horizontal"&&that.fullScreen){$stage.css("height",$WINDOW.height()-$nav.height())}if(o_nav){switch(opts.navdir){case"vertical":$navWrap.removeClass(navShafthorizontalClass);$navWrap.removeClass(navShaftListClass);$navWrap.addClass(navShaftVerticalClass);$nav.stop().animate({height:measures.h,width:opts.thumbwidth},time);break;case"list":$navWrap.removeClass(navShaftVerticalClass);$navWrap.removeClass(navShafthorizontalClass);$navWrap.addClass(navShaftListClass);break;default:$navWrap.removeClass(navShaftVerticalClass);$navWrap.removeClass(navShaftListClass);$navWrap.addClass(navShafthorizontalClass);$nav.stop().animate({width:measures.nw},time);break}stageShaftReposition();slideNavShaft({guessIndex:activeIndex,time:time,keep:true});if(o_navThumbs&&frameAppend.nav)slideThumbBorder(time)}measuresSetFLAG=setFLAG||true;ready.ok=true;ready()}}stageLeft=$stage.offset().left;setStagePosition();return this};that.setOptions=function(options){$.extend(opts,options);reset();return this};that.shuffle=function(){data&&shuffle(data)&&reset();return this};function setShadow($el,edge){if(o_shadows){$el.removeClass(shadowsLeftClass+" "+shadowsRightClass);$el.removeClass(shadowsTopClass+" "+shadowsBottomClass);edge&&!$videoPlaying&&$el.addClass(edge.replace(/^|\s/g," "+shadowsClass+"--"))}}that.longPress={threshold:1,count:0,thumbSlideTime:20,progress:function(){if(!this.inProgress){this.count++;this.inProgress=this.count>this.threshold}},end:function(){if(this.inProgress){this.isEnded=true}},reset:function(){this.count=0;this.inProgress=false;this.isEnded=false}};that.destroy=function(){that.cancelFullScreen();that.stopAutoplay();data=that.data=null;appendElements();activeIndexes=[];detachFrames(STAGE_FRAME_KEY);reset.ok=false;return this};that.playVideo=function(){var dataFrame=activeFrame,video=dataFrame.video,_activeIndex=activeIndex;if(typeof video==="object"&&dataFrame.videoReady){o_nativeFullScreen&&that.fullScreen&&that.cancelFullScreen();waitFor(function(){return!fullScreenApi.is()||_activeIndex!==activeIndex},function(){if(_activeIndex===activeIndex){dataFrame.$video=dataFrame.$video||$(div(videoClass)).append(createVideoFrame(video));dataFrame.$video.appendTo(dataFrame[STAGE_FRAME_KEY]);$wrap.addClass(wrapVideoClass);$videoPlaying=dataFrame.$video;stageNoMove();$arrs.blur();$fullscreenIcon.blur();triggerEvent("loadvideo")}})}return this};that.stopVideo=function(){unloadVideo($videoPlaying,true,true);return this};that.spliceByIndex=function(index,newImgObj){newImgObj.i=index+1;newImgObj.img&&$.ajax({url:newImgObj.img,type:"HEAD",success:function(){data.splice(index,1,newImgObj);reset()}})};function unloadVideo($video,unloadActiveFLAG,releaseAutoplayFLAG){if(unloadActiveFLAG){$wrap.removeClass(wrapVideoClass);$videoPlaying=false;stageNoMove()}if($video&&$video!==$videoPlaying){$video.remove();triggerEvent("unloadvideo")}if(releaseAutoplayFLAG){releaseAutoplay();changeAutoplay()}}function toggleControlsClass(FLAG){$wrap.toggleClass(wrapNoControlsClass,FLAG)}function stageCursor(e){if(stageShaftTouchTail.flow)return;var x=e?e.pageX:stageCursor.x,pointerFLAG=x&&!disableDirrection(getDirection(x))&&opts.click;if(stageCursor.p!==pointerFLAG&&$stage.toggleClass(pointerClass,pointerFLAG)){stageCursor.p=pointerFLAG;stageCursor.x=x}}$stage.on("mousemove",stageCursor);function clickToShow(showOptions){clearTimeout(clickToShow.t);if(opts.clicktransition&&opts.clicktransition!==opts.transition){setTimeout(function(){var _o_transition=opts.transition;that.setOptions({transition:opts.clicktransition});o_transition=_o_transition;clickToShow.t=setTimeout(function(){that.show(showOptions)},10)},0)}else{that.show(showOptions)}}function onStageTap(e,toggleControlsFLAG){var target=e.target,$target=$(target);if($target.hasClass(videoPlayClass)){that.playVideo()}else if(target===fullscreenIcon){that.toggleFullScreen()}else if($videoPlaying){target===videoClose&&unloadVideo($videoPlaying,true,true)}else if(!$fotorama.hasClass(fullscreenClass)){that.requestFullScreen()}}function updateTouchTails(key,value){stageShaftTouchTail[key]=navShaftTouchTail[key]=value}stageShaftTouchTail=moveOnTouch($stageShaft,{onStart:onTouchStart,onMove:function(e,result){setShadow($stage,result.edge)},onTouchEnd:onTouchEnd,onEnd:function(result){var toggleControlsFLAG;setShadow($stage);toggleControlsFLAG=(MS_POINTER&&!hoverFLAG||result.touch)&&opts.arrows;if((result.moved||toggleControlsFLAG&&result.pos!==result.newPos&&!result.control)&&result.$target[0]!==$fullscreenIcon[0]){var index=getIndexByPos(result.newPos,measures.w,opts.margin,repositionIndex);that.show({index:index,time:o_fade?o_transitionDuration:result.time,overPos:result.overPos,user:true})}else if(!result.aborted&&!result.control){onStageTap(result.startEvent,toggleControlsFLAG)}},timeLow:1,timeHigh:1,friction:2,select:"."+selectClass+", ."+selectClass+" *",$wrap:$stage,direction:"horizontal"});navShaftTouchTail=moveOnTouch($navShaft,{onStart:onTouchStart,onMove:function(e,result){setShadow($nav,result.edge)},onTouchEnd:onTouchEnd,onEnd:function(result){function onEnd(){slideNavShaft.l=result.newPos;releaseAutoplay();changeAutoplay();thumbsDraw(result.newPos,true);thumbArrUpdate()}if(!result.moved){var target=result.$target.closest("."+navFrameClass,$navShaft)[0];target&&onNavFrameClick.call(target,result.startEvent)}else if(result.pos!==result.newPos){pausedAutoplayFLAG=true;slide($navShaft,{time:result.time,pos:result.newPos,overPos:result.overPos,direction:opts.navdir,onEnd:onEnd});thumbsDraw(result.newPos);o_shadows&&setShadow($nav,findShadowEdge(result.newPos,navShaftTouchTail.min,navShaftTouchTail.max,result.dir))}else{onEnd()}},timeLow:.5,timeHigh:2,friction:5,$wrap:$nav,direction:opts.navdir});stageWheelTail=wheel($stage,{shift:true,onEnd:function(e,direction){onTouchStart();onTouchEnd();that.show({index:direction,slow:e.altKey})}});navWheelTail=wheel($nav,{onEnd:function(e,direction){onTouchStart();onTouchEnd();var newPos=stop($navShaft)+direction*.25;$navShaft.css(getTranslate(minMaxLimit(newPos,navShaftTouchTail.min,navShaftTouchTail.max),opts.navdir));o_shadows&&setShadow($nav,findShadowEdge(newPos,navShaftTouchTail.min,navShaftTouchTail.max,opts.navdir));navWheelTail.prevent={"<":newPos>=navShaftTouchTail.max,">":newPos<=navShaftTouchTail.min};clearTimeout(navWheelTail.t);navWheelTail.t=setTimeout(function(){slideNavShaft.l=newPos;thumbsDraw(newPos,true)},TOUCH_TIMEOUT);thumbsDraw(newPos)}});$wrap.hover(function(){setTimeout(function(){if(touchedFLAG)return;toggleControlsClass(!(hoverFLAG=true))},0)},function(){if(!hoverFLAG)return;toggleControlsClass(!(hoverFLAG=false))});function onNavFrameClick(e){var index=$(this).data().eq;if(opts.navtype==="thumbs"){clickToShow({index:index,slow:e.altKey,user:true,coo:e._x-$nav.offset().left})}else{clickToShow({index:index,slow:e.altKey,user:true})}}function onArrClick(e){clickToShow({index:$arrs.index(this)?">":"<",slow:e.altKey,user:true})}smartClick($arrs,function(e){stopEvent(e);onArrClick.call(this,e)},{onStart:function(){onTouchStart();stageShaftTouchTail.control=true},onTouchEnd:onTouchEnd});smartClick($thumbArrLeft,function(e){stopEvent(e);if(opts.navtype==="thumbs"){that.show("<")}else{that.showSlide("prev")}});smartClick($thumbArrRight,function(e){stopEvent(e);if(opts.navtype==="thumbs"){that.show(">")}else{that.showSlide("next")}});function addFocusOnControls(el){addFocus(el,function(){setTimeout(function(){lockScroll($stage)},0);toggleControlsClass(false)})}$arrs.each(function(){addEnterUp(this,function(e){onArrClick.call(this,e)});addFocusOnControls(this)});addEnterUp(fullscreenIcon,function(){if($fotorama.hasClass(fullscreenClass)){that.cancelFullScreen();$stageShaft.focus()}else{that.requestFullScreen();$fullscreenIcon.focus()}});addFocusOnControls(fullscreenIcon);function reset(){setData();setOptions();if(!reset.i){reset.i=true;var _startindex=opts.startindex;activeIndex=repositionIndex=dirtyIndex=lastActiveIndex=startIndex=edgeIndex(_startindex)||0}if(size){if(changeToRtl())return;if($videoPlaying){unloadVideo($videoPlaying,true)}activeIndexes=[];detachFrames(STAGE_FRAME_KEY);reset.ok=true;that.show({index:activeIndex,time:0});that.resize()}else{that.destroy()}}function changeToRtl(){if(!changeToRtl.f===o_rtl){changeToRtl.f=o_rtl;activeIndex=size-1-activeIndex;that.reverse();return true}}$.each("load push pop shift unshift reverse sort splice".split(" "),function(i,method){that[method]=function(){data=data||[];if(method!=="load"){Array.prototype[method].apply(data,arguments)}else if(arguments[0]&&typeof arguments[0]==="object"&&arguments[0].length){data=clone(arguments[0])}reset();return that}});function ready(){if(ready.ok){ready.ok=false;triggerEvent("ready")}}reset()};$.fn.fotorama=function(opts){return this.each(function(){var that=this,$fotorama=$(this),fotoramaData=$fotorama.data(),fotorama=fotoramaData.fotorama;if(!fotorama){waitFor(function(){return!isHidden(that)},function(){fotoramaData.urtext=$fotorama.html();new $.Fotorama($fotorama,$.extend({},OPTIONS,window.fotoramaDefaults,opts,fotoramaData))})}else{fotorama.setOptions(opts,true)}})};$.Fotorama.instances=[];function calculateIndexes(){$.each($.Fotorama.instances,function(index,instance){instance.index=index})}function addInstance(instance){$.Fotorama.instances.push(instance);calculateIndexes()}function hideInstance(instance){$.Fotorama.instances.splice(instance.index,1);calculateIndexes()}$.Fotorama.cache={};$.Fotorama.measures={};$=$||{};$.Fotorama=$.Fotorama||{};$.Fotorama.jst=$.Fotorama.jst||{};$.Fotorama.jst.dots=function(v){var __t,__p="",__e=_.escape;__p+='<div class="fotorama__nav__frame fotorama__nav__frame--dot" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n <div class="fotorama__dot"></div>\r\n</div>';return __p};$.Fotorama.jst.frameCaption=function(v){var __t,__p="",__e=_.escape;__p+='<div class="fotorama__caption" aria-hidden="true">\r\n <div class="fotorama__caption__wrap" id="'+((__t=v.labelledby)==null?"":__t)+'">'+((__t=v.caption)==null?"":__t)+"</div>\r\n</div>\r\n";return __p};$.Fotorama.jst.style=function(v){var __t,__p="",__e=_.escape;__p+=".fotorama"+((__t=v.s)==null?"":__t)+" .fotorama__nav--thumbs .fotorama__nav__frame{\r\npadding:"+((__t=v.m)==null?"":__t)+"px;\r\nheight:"+((__t=v.h)==null?"":__t)+"px}\r\n.fotorama"+((__t=v.s)==null?"":__t)+" .fotorama__thumb-border{\r\nheight:"+((__t=v.h)==null?"":__t)+"px;\r\nborder-width:"+((__t=v.b)==null?"":__t)+"px;\r\nmargin-top:"+((__t=v.m)==null?"":__t)+"px}";return __p};$.Fotorama.jst.thumb=function(v){var __t,__p="",__e=_.escape;__p+='<div class="fotorama__nav__frame fotorama__nav__frame--thumb" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n <div class="fotorama__thumb">\r\n </div>\r\n</div>';return __p}})(window,document,location,typeof jQuery!=="undefined"&&jQuery); From 8f9a7cdec76e1225e4c46d101d5643d742bf757c Mon Sep 17 00:00:00 2001 From: Stjepan Udovicic <stjepan.udovicic@inchoo.net> Date: Sun, 14 Oct 2018 21:17:28 +0200 Subject: [PATCH 308/812] Ensure integer values are not quoted as strings --- .../ProductCategoryCondition.php | 2 +- .../Magento/Catalog/Model/ProductCategoryList.php | 6 +++++- .../Model/ResourceModel/Product/Collection.php | 15 ++++++++++----- lib/internal/Magento/Framework/Mview/View.php | 2 +- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php index f70bab73d0830..d37f97c38a4f6 100644 --- a/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php +++ b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php @@ -104,7 +104,7 @@ private function getCategoryIds(Filter $filter): array } } - return array_unique(array_merge($categoryIds, ...$childCategoryIds)); + return array_map('intval', array_unique(array_merge($categoryIds, ...$childCategoryIds))); } /** diff --git a/app/code/Magento/Catalog/Model/ProductCategoryList.php b/app/code/Magento/Catalog/Model/ProductCategoryList.php index 5bbae772d5c2b..c8b075ffb494e 100644 --- a/app/code/Magento/Catalog/Model/ProductCategoryList.php +++ b/app/code/Magento/Catalog/Model/ProductCategoryList.php @@ -80,7 +80,11 @@ public function getCategoryIds($productId) Select::SQL_UNION_ALL ); - $this->categoryIdList[$productId] = $this->productResource->getConnection()->fetchCol($unionSelect); + $this->categoryIdList[$productId] = array_map( + 'intval', + $this->productResource->getConnection()->fetchCol($unionSelect) + ); + } return $this->categoryIdList[$productId]; diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 0d62d120f80e0..5afac59b25db6 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -1809,7 +1809,8 @@ protected function _productLimitationJoinWebsite() } $conditions[] = $this->getConnection()->quoteInto( 'product_website.website_id IN(?)', - $filters['website_ids'] + $filters['website_ids'], + 'int' ); } elseif (isset( $filters['store_id'] @@ -1821,7 +1822,7 @@ protected function _productLimitationJoinWebsite() ) { $joinWebsite = true; $websiteId = $this->_storeManager->getStore($filters['store_id'])->getWebsiteId(); - $conditions[] = $this->getConnection()->quoteInto('product_website.website_id = ?', $websiteId); + $conditions[] = $this->getConnection()->quoteInto('product_website.website_id = ?', $websiteId, 'int'); } $fromPart = $this->getSelect()->getPart(\Magento\Framework\DB\Select::FROM); @@ -2017,12 +2018,16 @@ protected function _applyProductLimitations() $conditions = [ 'cat_index.product_id=e.entity_id', - $this->getConnection()->quoteInto('cat_index.store_id=?', $filters['store_id']), + $this->getConnection()->quoteInto('cat_index.store_id=?', $filters['store_id'], 'int'), ]; if (isset($filters['visibility']) && !isset($filters['store_table'])) { - $conditions[] = $this->getConnection()->quoteInto('cat_index.visibility IN(?)', $filters['visibility']); + $conditions[] = $this->getConnection()->quoteInto( + 'cat_index.visibility IN(?)', + $filters['visibility'], + 'int' + ); } - $conditions[] = $this->getConnection()->quoteInto('cat_index.category_id=?', $filters['category_id']); + $conditions[] = $this->getConnection()->quoteInto('cat_index.category_id=?', $filters['category_id'], 'int'); if (isset($filters['category_is_anchor'])) { $conditions[] = $this->getConnection()->quoteInto('cat_index.is_parent=?', $filters['category_is_anchor']); } diff --git a/lib/internal/Magento/Framework/Mview/View.php b/lib/internal/Magento/Framework/Mview/View.php index a937c62dfc23a..589034886010f 100644 --- a/lib/internal/Magento/Framework/Mview/View.php +++ b/lib/internal/Magento/Framework/Mview/View.php @@ -283,7 +283,7 @@ public function update() for ($vsFrom = $lastVersionId; $vsFrom < $currentVersionId; $vsFrom += $versionBatchSize) { // Don't go past the current version for atomicy. $versionTo = min($currentVersionId, $vsFrom + $versionBatchSize); - $ids = $this->getChangelog()->getList($vsFrom, $versionTo); + $ids = array_map('intval', $this->getChangelog()->getList($vsFrom, $versionTo)); // We run the actual indexer in batches. // Chunked AFTER loading to avoid duplicates in separate chunks. From 44e89c730a48552eaa170a858486abfb601fd4b5 Mon Sep 17 00:00:00 2001 From: deninchoo <deni.pesic@inchoo.net> Date: Mon, 15 Oct 2018 09:58:11 +0200 Subject: [PATCH 309/812] Added check if array when validating request data --- .../Magento/Braintree/Controller/Paypal/Review.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Braintree/Controller/Paypal/Review.php b/app/code/Magento/Braintree/Controller/Paypal/Review.php index ca252aabe54a9..98a33b52f98eb 100644 --- a/app/code/Magento/Braintree/Controller/Paypal/Review.php +++ b/app/code/Magento/Braintree/Controller/Paypal/Review.php @@ -91,11 +91,15 @@ public function execute() } /** - * @param array $requestData - * @return boolean + * @param $requestData + * @return bool */ - private function validateRequestData(array $requestData) + private function validateRequestData($requestData) { - return !empty($requestData['nonce']) && !empty($requestData['details']); + if (is_array($requestData)) { + return !empty($requestData['nonce']) && !empty($requestData['details']); + } else { + return false; + } } } From 43cb06482fe187642722c486c4232edc10bd84ee Mon Sep 17 00:00:00 2001 From: deninchoo <deni.pesic@inchoo.net> Date: Mon, 15 Oct 2018 11:46:04 +0200 Subject: [PATCH 310/812] Simplified validateRequestData to work without an else expression --- app/code/Magento/Braintree/Controller/Paypal/Review.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Braintree/Controller/Paypal/Review.php b/app/code/Magento/Braintree/Controller/Paypal/Review.php index 98a33b52f98eb..964b0bde135ae 100644 --- a/app/code/Magento/Braintree/Controller/Paypal/Review.php +++ b/app/code/Magento/Braintree/Controller/Paypal/Review.php @@ -98,8 +98,7 @@ private function validateRequestData($requestData) { if (is_array($requestData)) { return !empty($requestData['nonce']) && !empty($requestData['details']); - } else { - return false; } + return false; } } From 42ecb9c78de2ebb4c1c475b2ef2e286faded0b5f Mon Sep 17 00:00:00 2001 From: Lewis Voncken <lewis@experius.nl> Date: Mon, 15 Oct 2018 15:47:35 +0200 Subject: [PATCH 311/812] [BUGFIX] [issue-10205] Always set the entity_type_id for updating product attributes because the route contains the specification products/attributes --- .../Catalog/Model/Product/Attribute/Repository.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php index f6d3ca36c1e1e..48ca12321a250 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php @@ -106,6 +106,11 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr */ public function save(\Magento\Catalog\Api\Data\ProductAttributeInterface $attribute) { + $attribute->setEntityTypeId( + $this->eavConfig + ->getEntityType(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE) + ->getId() + ); if ($attribute->getAttributeId()) { $existingModel = $this->get($attribute->getAttributeCode()); @@ -144,11 +149,6 @@ public function save(\Magento\Catalog\Api\Data\ProductAttributeInterface $attrib $attribute->setBackendModel( $this->productHelper->getAttributeBackendModelByInputType($attribute->getFrontendInput()) ); - $attribute->setEntityTypeId( - $this->eavConfig - ->getEntityType(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE) - ->getId() - ); $attribute->setIsUserDefined(1); } if (!empty($attribute->getData(AttributeInterface::OPTIONS))) { From 3f0e9a433b98577376f286e9935f1fd717a92c27 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 15 Oct 2018 17:28:26 +0200 Subject: [PATCH 312/812] Fixed incorrect datepicker icon position in admin panel --- .../backend/web/css/source/components/_calendar-temp.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less index 5ba18af6b0547..11b187db3d1e4 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_calendar-temp.less @@ -43,7 +43,7 @@ height: @action__height; margin-left: -@action__height; overflow: hidden; - position: relative; + position: absolute; vertical-align: top; z-index: 1; From 584eb7d6c876ea8c20e8a032ebddb43f5f8d3553 Mon Sep 17 00:00:00 2001 From: Matei Purcaru <matei.purcaru@gmail.com> Date: Mon, 15 Oct 2018 19:46:32 +0300 Subject: [PATCH 313/812] magento/graphql-ce#41: Fixed typos --- .../SalesGraphQl/Model/Resolver/Orders.php | 4 +- app/code/Magento/SalesGraphQl/README.md | 4 +- .../Magento/SalesGraphQl/etc/schema.graphqls | 11 ++-- dev/tests/api-functional/phpunit.xml.dist | 56 ------------------- .../Magento/GraphQl/Sales/OrdersTest.php | 12 ++-- 5 files changed, 13 insertions(+), 74 deletions(-) delete mode 100644 dev/tests/api-functional/phpunit.xml.dist diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php index c6c6ac6203789..91078c1580634 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php @@ -68,15 +68,13 @@ public function resolve( $orders = $this->collectionFactory->create($customerId); $items = []; - // @TODO Add shipping & billing address in response - // @TODO Add order currency object in response /** @var \Magento\Sales\Model\Order $order */ foreach ($orders as $order) { $items[] = [ 'id' => $order->getId(), 'increment_id' => $order->getIncrementId(), 'created_at' => $order->getCreatedAt(), - 'grant_total' => $order->getGrandTotal(), + 'grand_total' => $order->getGrandTotal(), 'state' => $order->getState(), 'status' => $order->getStatus() ]; diff --git a/app/code/Magento/SalesGraphQl/README.md b/app/code/Magento/SalesGraphQl/README.md index d827613570bad..d5717821b164c 100644 --- a/app/code/Magento/SalesGraphQl/README.md +++ b/app/code/Magento/SalesGraphQl/README.md @@ -1,6 +1,4 @@ # SalesGraphQl **SalesGraphQl** provides type and resolver information for the GraphQl module -to generate sales orders information endpoints. - -Also will provides endpoints for modifying an order. +to generate sales orders information. diff --git a/app/code/Magento/SalesGraphQl/etc/schema.graphqls b/app/code/Magento/SalesGraphQl/etc/schema.graphqls index c137484cd2f65..44f106532858f 100644 --- a/app/code/Magento/SalesGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SalesGraphQl/etc/schema.graphqls @@ -2,18 +2,17 @@ # See COPYING.txt for license details. type Query { - customerOrders: Orders @resolver(class: "Magento\\SalesGraphQl\\Model\\Resolver\\Orders") @doc(description: "List of customer orders") + customerOrders: CustomerOrders @resolver(class: "Magento\\SalesGraphQl\\Model\\Resolver\\Orders") @doc(description: "List of customer orders") } -type Order @doc(description: "Order mapping fields") { +type CustomerOrder @doc(description: "Order mapping fields") { id: Int increment_id: String created_at: String - grant_total: Float - state: String + grand_total: Float status: String } -type Orders { - items: [Order] @doc(description: "Array of orders") +type CustomerOrders { + items: [CustomerOrder] @doc(description: "Array of orders") } diff --git a/dev/tests/api-functional/phpunit.xml.dist b/dev/tests/api-functional/phpunit.xml.dist deleted file mode 100644 index c869608462d08..0000000000000 --- a/dev/tests/api-functional/phpunit.xml.dist +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- -/** - * PHPUnit configuration for GraphQL web API functional tests. - * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.2/phpunit.xsd" - colors="true" - columns="max" - beStrictAboutTestsThatDoNotTestAnything="false" - bootstrap="./framework/bootstrap.php" -> - <!-- Test suites definition --> - <testsuites> - <testsuite name="Magento GraphQL web API functional tests"> - <directory suffix="Test.php">testsuite/Magento/GraphQl</directory> - </testsuite> - </testsuites> - - <!-- PHP INI settings and constants definition --> - <php> - <includePath>./testsuite</includePath> - <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/> - <const name="TESTS_GLOBAL_CONFIG_FILE" value="config/config-global.php"/> - <!-- Webserver URL --> - <const name="TESTS_BASE_URL" value="http://magento.inno"/> - <!-- Webserver API user --> - <const name="TESTS_WEBSERVICE_USER" value="admin"/> - <!-- Webserver API key --> - <const name="TESTS_WEBSERVICE_APIKEY" value="123123q"/> - <!-- Define if debugger should be started using XDEBUG_SESSION cookie --> - <const name="TESTS_XDEBUG_ENABLED" value="true"/> - <!-- Define XDEBUG_SESSION cookie value--> - <const name="TESTS_XDEBUG_SESSION" value="MEETMAGENTO" /> - - <ini name="date.timezone" value="America/Los_Angeles"/> - - <!-- Semicolon-separated 'glob' patterns, that match global XML configuration files --> - <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> - <!-- Whether to cleanup the application before running tests or not --> - <const name="TESTS_CLEANUP" value="enabled"/> - <!--Defines if Magento should be installed before tests execution--> - <const name="TESTS_MAGENTO_INSTALLATION" value="disabled"/> - <!-- Magento mode for tests execution. Possible values are "default", "developer" and "production". --> - <const name="TESTS_MAGENTO_MODE" value="default"/> - </php> - - <!-- Test listeners --> - <listeners> - <listener class="Magento\TestFramework\Event\PhpUnit"/> - </listeners> -</phpunit> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php index 3a85c044f16a9..ef7ceebc3a053 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php @@ -63,31 +63,31 @@ public function testOrdersQuery() 'increment_id' => '100000002', 'state' => \Magento\Sales\Model\Order::STATE_NEW, 'status' => 'processing', - 'grant_total' => 120.00 + 'grand_total' => 120.00 ], [ 'increment_id' => '100000003', 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, 'status' => 'processing', - 'grant_total' => 130.00 + 'grand_total' => 130.00 ], [ 'increment_id' => '100000004', 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, 'status' => 'closed', - 'grant_total' => 140.00 + 'grand_total' => 140.00 ], [ 'increment_id' => '100000005', 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, 'status' => 'complete', - 'grant_total' => 150.00 + 'grand_total' => 150.00 ], [ 'increment_id' => '100000006', 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, 'status' => 'complete', - 'grant_total' => 160.00 + 'grand_total' => 160.00 ] ]; @@ -95,7 +95,7 @@ public function testOrdersQuery() foreach ($expectedData as $key => $data) { $this->assertEquals($data['increment_id'], $actualData[$key]['increment_id']); - $this->assertEquals($data['grant_total'], $actualData[$key]['grant_total']); + $this->assertEquals($data['grand_total'], $actualData[$key]['grand_total']); $this->assertEquals($data['state'], $actualData[$key]['state']); $this->assertEquals($data['status'], $actualData[$key]['status']); } From 4a31f4f11972bf69fdbbe125fd262f9dfdfed0de Mon Sep 17 00:00:00 2001 From: Matei Purcaru <matei.purcaru@gmail.com> Date: Mon, 15 Oct 2018 19:55:48 +0300 Subject: [PATCH 314/812] magento/graphql-ce#41: get user info from resolver context --- .../SalesGraphQl/Model/Resolver/Orders.php | 29 +++++++------------ .../Magento/GraphQl/Sales/OrdersTest.php | 23 +++++---------- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php index 91078c1580634..05af6829de454 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php @@ -15,15 +15,10 @@ use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccountInterface; /** - * {@inheritdoc} + * Class Orders */ class Orders implements ResolverInterface { - /** - * @var UserContextInterface - */ - private $userContext; - /** * @var CollectionFactoryInterface */ @@ -36,15 +31,13 @@ class Orders implements ResolverInterface /** * Orders constructor. - * @param UserContextInterface $userContext * @param CollectionFactoryInterface $collectionFactory + * @param CheckCustomerAccountInterface $checkCustomerAccount */ public function __construct( - UserContextInterface $userContext, CollectionFactoryInterface $collectionFactory, CheckCustomerAccountInterface $checkCustomerAccount ) { - $this->userContext = $userContext; $this->collectionFactory = $collectionFactory; $this->checkCustomerAccount = $checkCustomerAccount; @@ -55,18 +48,17 @@ public function __construct( */ public function resolve( Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null + $context, + ResolveInfo $info, + array $value = null, + array $args = null ) { + $customerId = $context->getUserId(); - $customerId = $this->userContext->getUserId(); + $this->checkCustomerAccount->execute($customerId, $context->getUserType()); - $this->checkCustomerAccount->execute($customerId, $this->userContext->getUserType()); - - $orders = $this->collectionFactory->create($customerId); $items = []; + $orders = $this->collectionFactory->create($customerId); /** @var \Magento\Sales\Model\Order $order */ foreach ($orders as $order) { @@ -75,11 +67,10 @@ public function resolve( 'increment_id' => $order->getIncrementId(), 'created_at' => $order->getCreatedAt(), 'grand_total' => $order->getGrandTotal(), - 'state' => $order->getState(), 'status' => $order->getStatus() ]; } return ['items' => $items]; } -} \ No newline at end of file +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php index ef7ceebc3a053..33620f6e55386 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php @@ -40,16 +40,15 @@ public function testOrdersQuery() $query = <<<QUERY query { - customerOrders { - items { - id - increment_id - created_at - grant_total - state - status - } + customerOrders { + items { + id + increment_id + created_at + grand_total + status } + } } QUERY; @@ -61,31 +60,26 @@ public function testOrdersQuery() $expectedData = [ [ 'increment_id' => '100000002', - 'state' => \Magento\Sales\Model\Order::STATE_NEW, 'status' => 'processing', 'grand_total' => 120.00 ], [ 'increment_id' => '100000003', - 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, 'status' => 'processing', 'grand_total' => 130.00 ], [ 'increment_id' => '100000004', - 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, 'status' => 'closed', 'grand_total' => 140.00 ], [ 'increment_id' => '100000005', - 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, 'status' => 'complete', 'grand_total' => 150.00 ], [ 'increment_id' => '100000006', - 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, 'status' => 'complete', 'grand_total' => 160.00 ] @@ -96,7 +90,6 @@ public function testOrdersQuery() foreach ($expectedData as $key => $data) { $this->assertEquals($data['increment_id'], $actualData[$key]['increment_id']); $this->assertEquals($data['grand_total'], $actualData[$key]['grand_total']); - $this->assertEquals($data['state'], $actualData[$key]['state']); $this->assertEquals($data['status'], $actualData[$key]['status']); } } From 94f25c3ba8dffb00ab31c3cdc9a6262b42fabee6 Mon Sep 17 00:00:00 2001 From: pganapat <prabhuramgr28493@gmail.com> Date: Mon, 15 Oct 2018 12:17:26 -0500 Subject: [PATCH 315/812] MAGETWO-95213: Updating Product Status With Mass Action By Scope Updates The Default Value - Added short class description. --- .../Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php index 83278ca78c738..9d7273fb3f23c 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php @@ -14,6 +14,7 @@ use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; /** + * Updates status for a batch of products. * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class MassStatus extends \Magento\Catalog\Controller\Adminhtml\Product implements HttpPostActionInterface From e30a12e6bf954763662f68f5eec87d2cbc2e93dd Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh@Maheshs-MacBook-Air.local> Date: Tue, 16 Oct 2018 00:08:57 +0530 Subject: [PATCH 316/812] reference pull request of #18604 for 2.3-develop --- app/code/Magento/Catalog/Pricing/Price/BasePrice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Pricing/Price/BasePrice.php b/app/code/Magento/Catalog/Pricing/Price/BasePrice.php index 54a13be864db7..77368517a3155 100644 --- a/app/code/Magento/Catalog/Pricing/Price/BasePrice.php +++ b/app/code/Magento/Catalog/Pricing/Price/BasePrice.php @@ -30,7 +30,7 @@ public function getValue() $this->value = false; foreach ($this->priceInfo->getPrices() as $price) { if ($price instanceof BasePriceProviderInterface && $price->getValue() !== false) { - $this->value = min($price->getValue(), $this->value ?: $price->getValue()); + $this->value = min($price->getValue(), $this->value !== false ? $this->value: $price->getValue()); } } } From ac457a482c948abc3f99a4803005035a31950dc8 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Mon, 15 Oct 2018 15:19:16 -0500 Subject: [PATCH 317/812] MAGETWO-95532: Unable to upload image from TinyMCE3 - added functional test to cover the bug fix --- .../Cms/Test/Mftf/Section/TinyMCESection.xml | 2 + .../AdminAddImageToCMSPageTinyMCE3Test.xml | 80 +++++++++++++++++++ .../Section/AdminTinymce3FileldsSection.xml | 1 + 3 files changed, 83 insertions(+) create mode 100644 app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml diff --git a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml index 75a399720cd6a..ed682a9e20435 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml @@ -34,6 +34,7 @@ </section> <section name="MediaGallerySection"> <element name="Browse" type="button" selector=".mce-i-browse"/> + <element name="browseForImage" type="button" selector="//*[@id='srcbrowser']"/> <element name="BrowseUploadImage" type="file" selector=".fileupload" /> <element name="image" type="text" selector="//small[text()='{{var1}}']" parameterized="true"/> <element name="imageOrImageCopy" type="text" selector="//div[contains(@class,'media-gallery-modal')]//img[contains(@alt, '{{arg1}}.{{arg2}}')]|//img[contains(@alt,'{{arg1}}_') and contains(@alt,'.{{arg2}}')]" parameterized="true"/> @@ -43,6 +44,7 @@ <element name="Height" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-first" /> <element name="UploadImage" type="file" selector=".fileupload" /> <element name="OkBtn" type="button" selector="//span[text()='Ok']"/> + <element name="insertBtn" type="button" selector="#insert"/> <element name="InsertFile" type="text" selector="#insert_files"/> <element name="CreateFolder" type="button" selector="#new_folder" /> <element name="DeleteSelectedBtn" type="text" selector="#delete_files"/> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml new file mode 100644 index 0000000000000..125faa935f369 --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -0,0 +1,80 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminAddImageToCMSPageTinyMCE3Test"> + <annotations> + <features value="Cms"/> + <stories value="Admin should be able to upload images with TinyMCE3 WYSIWYG"/> + <group value="Cms"/> + <title value="Verify that admin is able to upload image to a CMS Page with TinyMCE3 enabled"/> + <description value="Verify that admin is able to upload image to CMS Page with TinyMCE3 enabled"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-95725"/> + </annotations> + <before> + <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> + <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> + <comment userInput="Choose TinyMCE3 as the default editor" stepKey="chooseTinyMCE3AsEditor"/> + <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox1" /> + <uncheckOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="uncheckUseSystemValue2"/> + <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown1" /> + <selectOption selector="{{ContentManagementSection.Switcher}}" userInput="TinyMCE 3" stepKey="switchToVersion3" /> + <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions1" /> + <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig1" /> + </before> + <after> + <comment userInput="Reset editor as TinyMCE4" stepKey="chooseTinyMCE4AsEditor"/> + <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToConfigurationPage" /> + <waitForPageLoad stepKey="waitForConfigPageToReload"/> + <conditionalClick stepKey="expandWYSIWYGOptions" selector="{{ContentManagementSection.WYSIWYGOptions}}" dependentSelector="{{ContentManagementSection.CheckIfTabExpand}}" visible="true" /> + <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox2" /> + + <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown3" /> + <selectOption selector="{{ContentManagementSection.Switcher}}" userInput="TinyMCE 4" stepKey="switchToVersion4" /> + <checkOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="checkUseSystemValue2"/> + <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions2" /> + <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig2" /> + <actionGroup ref="logout" stepKey="logOut"/> + </after> + <amOnPage url="{{CmsNewPagePage.url}}" stepKey="navigateToPage2"/> + <waitForPageLoad stepKey="wait5"/> + <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle2"/> + <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab2" /> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE3}}" stepKey="waitForTinyMCE3"/> + <seeElement selector="{{TinyMCESection.TinyMCE3}}" stepKey="seeTinyMCE3" /> + <comment userInput="Click Insert image button" stepKey="clickImageButton"/> + <click selector="{{TinyMCESection.InsertImageBtnTinyMCE3}}" stepKey="clickInsertImage" /> + <waitForPageLoad stepKey="waitForiFrameToLoad" /> + <comment userInput="switching to iFrame" stepKey="iFramecomment"/> + <executeJS function="document.querySelector('.clearlooks2 iframe').setAttribute('name', 'insert-image');" stepKey="makeIFrameInteractable"/> + <switchToIFrame selector="insert-image" stepKey="switchToIFrame"/> + <click selector="{{MediaGallerySection.browseForImage}}" stepKey="clickBrowse"/> + <switchToIFrame stepKey="switchOutOfIFrame"/> + <waitForPageLoad stepKey="waitForPageToLoad" /> + <actionGroup ref="CreateImageFolder" stepKey="CreateImageFolder"> + <argument name="ImageFolder" value="ImageFolder"/> + </actionGroup> + <actionGroup ref="attachImage" stepKey="attachImage1"> + <argument name="Image" value="ImageUpload"/> + </actionGroup> + <actionGroup ref="saveImage" stepKey="insertImage"/> + <comment userInput="switching back to iFrame" stepKey="switchBackToIFrame"/> + <executeJS function="document.querySelector('.clearlooks2 iframe').setAttribute('name', 'insert-image');" stepKey="makeIFrameInteractable2"/> + <switchToIFrame selector="insert-image" stepKey="switchToIFrame2"/> + <waitForElementVisible selector="{{MediaGallerySection.insertBtn}}" stepKey="waitForInsertBtnOnIFrame" /> + <fillField selector="{{MediaGallerySection.ImageDescription}}" userInput="{{ImageUpload.content}}" stepKey="fillImageDescription" /> + <click selector="{{MediaGallerySection.insertBtn}}" stepKey="clickInsertBtn" /> + <waitForPageLoad stepKey="wait3"/> + <click selector="{{CmsNewPagePageActionsSection.expandSplitButton}}" stepKey="expandButtonMenu"/> + <waitForElementVisible selector="{{CmsNewPagePageActionsSection.splitButtonMenu}}" stepKey="waitForSplitButtonMenuVisible"/> + <click selector="{{CmsNewPagePageActionsSection.savePage}}" stepKey="clickSavePage"/> + <see userInput="You saved the page." stepKey="seeSuccessMessage"/> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/Tinymce3/Test/Mftf/Section/AdminTinymce3FileldsSection.xml b/app/code/Magento/Tinymce3/Test/Mftf/Section/AdminTinymce3FileldsSection.xml index 1730996937ca2..76c0a9e1fe797 100644 --- a/app/code/Magento/Tinymce3/Test/Mftf/Section/AdminTinymce3FileldsSection.xml +++ b/app/code/Magento/Tinymce3/Test/Mftf/Section/AdminTinymce3FileldsSection.xml @@ -13,6 +13,7 @@ </section> <section name="TinyMCESection"> <element name="TinyMCE3" type="text" selector="#cms_page_form_content_tbl"/> + <element name="InsertImageBtnTinyMCE3" type="button" selector="#cms_page_form_content_image"/> </section> <section name="NewsletterWYSIWYGSection"> <element name="TinyMCE3" type="text" selector="#cms_page_form_content_tbl"/> From 954ee4fbecf96d3898bbad21d46f2430d6ebd544 Mon Sep 17 00:00:00 2001 From: Ayaz Mittaqi <ayaz.mittaqi024@webkul.com> Date: Tue, 16 Oct 2018 02:51:20 +0530 Subject: [PATCH 318/812] fixed issue regarding referer url of compare page during adding product to wishlist. --- .../Magento/Catalog/Block/Product/Compare/ListCompare.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php b/app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php index 6c54aa4e171ef..76f5dbd1bea88 100644 --- a/app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php +++ b/app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php @@ -122,12 +122,7 @@ public function __construct( */ public function getAddToWishlistParams($product) { - $continueUrl = $this->urlEncoder->encode($this->getUrl('customer/account')); - $urlParamName = Action::PARAM_NAME_URL_ENCODED; - - $continueUrlParams = [$urlParamName => $continueUrl]; - - return $this->_wishlistHelper->getAddParams($product, $continueUrlParams); + return $this->_wishlistHelper->getAddParams($product); } /** From c25ea8170a37bea2707bb311591da84c983ab513 Mon Sep 17 00:00:00 2001 From: Sachin Admane <sadmane@magento.com> Date: Mon, 15 Oct 2018 16:39:09 -0500 Subject: [PATCH 319/812] MAGETWO-95210: Unable to place orders as Guest after deleting PHPSESSID cookie value Modify convertCustomerCartToGuest function to get quote Id from getter method. --- app/code/Magento/Persistent/Model/QuoteManager.php | 2 +- .../Test/Unit/Model/QuoteManagerTest.php | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Persistent/Model/QuoteManager.php b/app/code/Magento/Persistent/Model/QuoteManager.php index 8937a4920cb23..cd7ce400a0be1 100644 --- a/app/code/Magento/Persistent/Model/QuoteManager.php +++ b/app/code/Magento/Persistent/Model/QuoteManager.php @@ -109,7 +109,7 @@ public function setGuest($checkQuote = false) public function convertCustomerCartToGuest() { /** @var $quote \Magento\Quote\Model\Quote */ - $quote = $this->quoteRepository->get($this->checkoutSession->getQuote()->getId()); + $quote = $this->quoteRepository->get($this->checkoutSession->getQuoteId()); if ($quote && $quote->getId()) { $this->_setQuotePersistent = false; $quote->setIsActive(true) diff --git a/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php b/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php index 5b96acae1d747..d8c5e4fc8167d 100644 --- a/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php +++ b/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php @@ -245,8 +245,8 @@ public function testConvertCustomerCartToGuest() $emailArgs = ['email' => null]; $this->checkoutSessionMock->expects($this->once()) - ->method('getQuote')->willReturn($this->quoteMock); - $this->quoteMock->expects($this->exactly(2))->method('getId')->willReturn($quoteId); + ->method('getQuoteId')->willReturn($quoteId); + $this->quoteMock->expects($this->once())->method('getId')->willReturn($quoteId); $this->quoteRepositoryMock->expects($this->once())->method('get')->with($quoteId)->willReturn($this->quoteMock); $this->quoteMock->expects($this->once()) ->method('setIsActive')->with(true)->willReturn($this->quoteMock); @@ -282,25 +282,23 @@ public function testConvertCustomerCartToGuest() $this->model->convertCustomerCartToGuest(); } - +E public function testConvertCustomerCartToGuestWithEmptyQuote() { $this->checkoutSessionMock->expects($this->once()) - ->method('getQuote')->willReturn($this->quoteMock); - $this->quoteMock->expects($this->once())->method('getId')->willReturn(null); + ->method('getQuoteId')->willReturn(null); $this->quoteRepositoryMock->expects($this->once())->method('get')->with(null)->willReturn(null); - $this->model->convertCustomerCartToGuest(); } public function testConvertCustomerCartToGuestWithEmptyQuoteId() { $this->checkoutSessionMock->expects($this->once()) - ->method('getQuote')->willReturn($this->quoteMock); - $this->quoteMock->expects($this->once())->method('getId')->willReturn(1); + ->method('getQuoteId')->willReturn(1); $quoteWithNoId = $this->quoteMock = $this->createMock(\Magento\Quote\Model\Quote::class); $quoteWithNoId->expects($this->once())->method('getId')->willReturn(null); $this->quoteRepositoryMock->expects($this->once())->method('get')->with(1)->willReturn($quoteWithNoId); + $this->quoteMock->expects($this->once())->method('getId')->willReturn(1); $this->model->convertCustomerCartToGuest(); } } From 551b89853bdcea5778eaa62e8237b20f1baeb52d Mon Sep 17 00:00:00 2001 From: Sachin Admane <sadmane@magento.com> Date: Mon, 15 Oct 2018 16:48:23 -0500 Subject: [PATCH 320/812] MAGETWO-95210: Unable to place orders as Guest after deleting PHPSESSID cookie value Fix typo in test. --- .../Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php b/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php index d8c5e4fc8167d..e5de8e7d4aade 100644 --- a/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php +++ b/app/code/Magento/Persistent/Test/Unit/Model/QuoteManagerTest.php @@ -282,7 +282,7 @@ public function testConvertCustomerCartToGuest() $this->model->convertCustomerCartToGuest(); } -E + public function testConvertCustomerCartToGuestWithEmptyQuote() { $this->checkoutSessionMock->expects($this->once()) From 6f14ad9d800fe0d0496de6b92fe5be7b8d87fd3a Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Mon, 15 Oct 2018 16:53:52 -0500 Subject: [PATCH 321/812] MAGETWO-95532: Unable to upload image from TinyMCE3 - modified after CR comments --- .../Cms/Test/Mftf/Section/TinyMCESection.xml | 1 + .../AdminAddImageToCMSPageTinyMCE3Test.xml | 27 ++++++------------- .../ActionGroup/ConfigWYSIWYGActionGroup.xml | 9 +++++++ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml index ed682a9e20435..92112661846c0 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml @@ -41,6 +41,7 @@ <element name="imageSelected" type="text" selector="//small[text()='{{var1}}']/parent::*[@class='filecnt selected']" parameterized="true"/> <element name="ImageSource" type="input" selector=".mce-combobox.mce-abs-layout-item.mce-last.mce-has-open" /> <element name="ImageDescription" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-last" /> + <element name="ImageDescriptionTinyMCE3" type="input" selector="#alt" /> <element name="Height" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-first" /> <element name="UploadImage" type="file" selector=".fileupload" /> <element name="OkBtn" type="button" selector="//span[text()='Ok']"/> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 125faa935f369..5ae3f4af2421e 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -21,26 +21,13 @@ <before> <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> - <comment userInput="Choose TinyMCE3 as the default editor" stepKey="chooseTinyMCE3AsEditor"/> - <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox1" /> - <uncheckOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="uncheckUseSystemValue2"/> - <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown1" /> - <selectOption selector="{{ContentManagementSection.Switcher}}" userInput="TinyMCE 3" stepKey="switchToVersion3" /> - <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions1" /> - <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig1" /> + <!-- Choose TinyMCE3 as the default WYSIWYG editor--> + <actionGroup ref="SwitchToTinyMCE3" stepKey="switchToTinyMCE3"/> </before> <after> + <!-- Switch WYSIWYG editor to TinyMCE4--> <comment userInput="Reset editor as TinyMCE4" stepKey="chooseTinyMCE4AsEditor"/> - <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToConfigurationPage" /> - <waitForPageLoad stepKey="waitForConfigPageToReload"/> - <conditionalClick stepKey="expandWYSIWYGOptions" selector="{{ContentManagementSection.WYSIWYGOptions}}" dependentSelector="{{ContentManagementSection.CheckIfTabExpand}}" visible="true" /> - <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox2" /> - - <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown3" /> - <selectOption selector="{{ContentManagementSection.Switcher}}" userInput="TinyMCE 4" stepKey="switchToVersion4" /> - <checkOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="checkUseSystemValue2"/> - <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions2" /> - <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig2" /> + <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4"/> <actionGroup ref="logout" stepKey="logOut"/> </after> <amOnPage url="{{CmsNewPagePage.url}}" stepKey="navigateToPage2"/> @@ -52,7 +39,8 @@ <comment userInput="Click Insert image button" stepKey="clickImageButton"/> <click selector="{{TinyMCESection.InsertImageBtnTinyMCE3}}" stepKey="clickInsertImage" /> <waitForPageLoad stepKey="waitForiFrameToLoad" /> - <comment userInput="switching to iFrame" stepKey="iFramecomment"/> + <!-- Switch to the Edit/Insert Image iFrame --> + <comment userInput="Switching to iFrame" stepKey="insertImageiFrame"/> <executeJS function="document.querySelector('.clearlooks2 iframe').setAttribute('name', 'insert-image');" stepKey="makeIFrameInteractable"/> <switchToIFrame selector="insert-image" stepKey="switchToIFrame"/> <click selector="{{MediaGallerySection.browseForImage}}" stepKey="clickBrowse"/> @@ -65,11 +53,12 @@ <argument name="Image" value="ImageUpload"/> </actionGroup> <actionGroup ref="saveImage" stepKey="insertImage"/> + <!-- Switching back to the Edit/Insert Image iFrame--> <comment userInput="switching back to iFrame" stepKey="switchBackToIFrame"/> <executeJS function="document.querySelector('.clearlooks2 iframe').setAttribute('name', 'insert-image');" stepKey="makeIFrameInteractable2"/> <switchToIFrame selector="insert-image" stepKey="switchToIFrame2"/> <waitForElementVisible selector="{{MediaGallerySection.insertBtn}}" stepKey="waitForInsertBtnOnIFrame" /> - <fillField selector="{{MediaGallerySection.ImageDescription}}" userInput="{{ImageUpload.content}}" stepKey="fillImageDescription" /> + <fillField selector="{{MediaGallerySection.ImageDescriptionTinyMCE3}}" userInput="{{ImageUpload.content}}" stepKey="fillImageDescription" /> <click selector="{{MediaGallerySection.insertBtn}}" stepKey="clickInsertBtn" /> <waitForPageLoad stepKey="wait3"/> <click selector="{{CmsNewPagePageActionsSection.expandSplitButton}}" stepKey="expandButtonMenu"/> diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml index 3c043b28801e2..836cba95a6d00 100644 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml @@ -19,6 +19,15 @@ <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions" /> <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig" /> </actionGroup> + <actionGroup name="SwitchToTinyMCE3"> + <comment userInput="Choose TinyMCE3 as the default editor" stepKey="chooseTinyMCE3AsEditor"/> + <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox2" /> + <uncheckOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="uncheckUseSystemValue2"/> + <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown2" /> + <selectOption selector="{{ContentManagementSection.Switcher}}" userInput="TinyMCE 3" stepKey="switchToVersion3" /> + <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions" /> + <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig" /> + </actionGroup> <actionGroup name="DisabledWYSIWYG"> <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToConfigurationPage" /> <waitForPageLoad stepKey="wait3"/> From 7106d24fd8911881874ca2e60e02b3161f680fbf Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Wed, 10 Oct 2018 13:02:33 -0500 Subject: [PATCH 322/812] MAGETWO-95161: Layered Navigation Price step field displays as Mandatory but user can save categories by leaving the field empty. --- .../Catalog/view/adminhtml/ui_component/category_form.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/ui_component/category_form.xml b/app/code/Magento/Catalog/view/adminhtml/ui_component/category_form.xml index dafea71f872d0..1a54db0d59f0f 100644 --- a/app/code/Magento/Catalog/view/adminhtml/ui_component/category_form.xml +++ b/app/code/Magento/Catalog/view/adminhtml/ui_component/category_form.xml @@ -331,7 +331,6 @@ <item name="type" xsi:type="string">group</item> <item name="config" xsi:type="array"> <item name="breakLine" xsi:type="boolean">true</item> - <item name="required" xsi:type="boolean">true</item> </item> </argument> <field name="filter_price_range" formElement="input"> @@ -341,6 +340,9 @@ </item> </argument> <settings> + <validation> + <rule name="required-entry" xsi:type="boolean">true</rule> + </validation> <additionalClasses> <class name="admin__field-small">true</class> </additionalClasses> From a9bc411deaecd93be411a3bc8c8da003b2e31298 Mon Sep 17 00:00:00 2001 From: Ravi Chandra <ravi.chandra@krishtechnolabs.com> Date: Tue, 16 Oct 2018 10:57:14 +0530 Subject: [PATCH 323/812] Fix SKU limit in import new products for 2.3 with backward compatible --- .../CatalogImportExport/Model/Import/Product/Validator.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php index 2aa2105991883..b184334b179ea 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php @@ -7,6 +7,7 @@ use Magento\CatalogImportExport\Model\Import\Product; use Magento\Framework\Validator\AbstractValidator; +use Magento\Catalog\Model\Product\Attribute\Backend\Sku; /** * Class Validator @@ -69,6 +70,8 @@ protected function textValidation($attrCode, $type) $val = $this->string->cleanString($this->_rowData[$attrCode]); if ($type == 'text') { $valid = $this->string->strlen($val) < Product::DB_MAX_TEXT_LENGTH; + } else if ($attrCode == Product::COL_SKU) { + $valid = $this->string->strlen($val) < SKU::SKU_MAX_LENGTH; } else { $valid = $this->string->strlen($val) < Product::DB_MAX_VARCHAR_LENGTH; } From 06237d69db44b491dfe57b29cf50d7c01b5b8c0c Mon Sep 17 00:00:00 2001 From: deninchoo <deni.pesic@inchoo.net> Date: Tue, 16 Oct 2018 08:53:19 +0200 Subject: [PATCH 324/812] Added check for truthy value of $requestData variable in case of null --- .../Magento/Braintree/Controller/Paypal/Review.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Braintree/Controller/Paypal/Review.php b/app/code/Magento/Braintree/Controller/Paypal/Review.php index 964b0bde135ae..e6a1dcbc34559 100644 --- a/app/code/Magento/Braintree/Controller/Paypal/Review.php +++ b/app/code/Magento/Braintree/Controller/Paypal/Review.php @@ -60,7 +60,7 @@ public function execute() try { $this->validateQuote($quote); - if ($this->validateRequestData($requestData)) { + if ($requestData && $this->validateRequestData($requestData)) { $this->quoteUpdater->execute( $requestData['nonce'], $requestData['details'], @@ -91,14 +91,11 @@ public function execute() } /** - * @param $requestData - * @return bool + * @param array $requestData + * @return boolean */ - private function validateRequestData($requestData) + private function validateRequestData(array $requestData) { - if (is_array($requestData)) { - return !empty($requestData['nonce']) && !empty($requestData['details']); - } - return false; + return !empty($requestData['nonce']) && !empty($requestData['details']); } } From 4d9fab4557a2c704b5f600841abff62778c74ce8 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 10 Oct 2018 16:10:25 +0300 Subject: [PATCH 325/812] MAGETWO-90021: [Catalog] ProductAttributeMediaGalleryManagementInterface removes product from index, impossible to restore - Make Gallery management to get product in editable mode. Fix test. --- .../Catalog/Model/Product/Gallery/GalleryManagement.php | 6 +++--- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php index 4d274a071d087..4be4bb09efc98 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php @@ -54,7 +54,7 @@ public function create($sku, ProductAttributeMediaGalleryEntryInterface $entry) if (!$this->contentValidator->isValid($entryContent)) { throw new InputException(__('The image content is invalid. Verify the content and try again.')); } - $product = $this->productRepository->get($sku); + $product = $this->productRepository->get($sku, true); $existingMediaGalleryEntries = $product->getMediaGalleryEntries(); $existingEntryIds = []; @@ -88,7 +88,7 @@ public function create($sku, ProductAttributeMediaGalleryEntryInterface $entry) */ public function update($sku, ProductAttributeMediaGalleryEntryInterface $entry) { - $product = $this->productRepository->get($sku); + $product = $this->productRepository->get($sku, true); $existingMediaGalleryEntries = $product->getMediaGalleryEntries(); if ($existingMediaGalleryEntries == null) { throw new NoSuchEntityException( @@ -129,7 +129,7 @@ public function update($sku, ProductAttributeMediaGalleryEntryInterface $entry) */ public function remove($sku, $entryId) { - $product = $this->productRepository->get($sku); + $product = $this->productRepository->get($sku, true); $existingMediaGalleryEntries = $product->getMediaGalleryEntries(); if ($existingMediaGalleryEntries == null) { throw new NoSuchEntityException( 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 34cebde64d03a..b9993b420f427 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -285,7 +285,6 @@ public function testQueryAllFieldsSimpleProduct() */ public function testQueryMediaGalleryEntryFieldsSimpleProduct() { - $this->markTestSkipped("Skipped until ticket MAGETWO-90021 is resolved."); $productSku = 'simple'; $query = <<<QUERY @@ -453,7 +452,9 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() } short_description sku - small_image + small_image { + path + } small_image_label special_from_date special_price From ecb1a7bf306e87eb54a08a7c5a19eac214838ce6 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 16 Oct 2018 13:10:15 +0200 Subject: [PATCH 326/812] Another attempt to execute tests --- .travis.yml | 22 ++++---- dev/tests/api-functional/phpunit.xml.dist | 56 ------------------- .../api-functional/phpunit_graphql.xml.dist | 2 +- dev/travis/before_install.sh | 2 +- dev/travis/before_script.sh | 29 ++++++++++ 5 files changed, 43 insertions(+), 68 deletions(-) delete mode 100644 dev/tests/api-functional/phpunit.xml.dist diff --git a/.travis.yml b/.travis.yml index c6077564b923d..930172a9ea6e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,14 +25,14 @@ env: - NODE_JS_VERSION=8 - MAGENTO_HOST_NAME="magento2.travis" matrix: - - TEST_SUITE=unit - - TEST_SUITE=static - - TEST_SUITE=js GRUNT_COMMAND=spec - - TEST_SUITE=js GRUNT_COMMAND=static - - TEST_SUITE=integration INTEGRATION_INDEX=1 - - TEST_SUITE=integration INTEGRATION_INDEX=2 - - TEST_SUITE=integration INTEGRATION_INDEX=3 - - TEST_SUITE=functional +# - TEST_SUITE=unit +# - TEST_SUITE=static +# - TEST_SUITE=js GRUNT_COMMAND=spec +# - TEST_SUITE=js GRUNT_COMMAND=static +# - TEST_SUITE=integration INTEGRATION_INDEX=1 +# - TEST_SUITE=integration INTEGRATION_INDEX=2 +# - TEST_SUITE=integration INTEGRATION_INDEX=3 +# - TEST_SUITE=functional - TEST_SUITE=api-functional matrix: exclude: @@ -44,6 +44,8 @@ matrix: env: TEST_SUITE=js GRUNT_COMMAND=static - php: 7.1 env: TEST_SUITE=functional + - php: 7.1 + env: TEST_SUITE=api-functional cache: apt: true directories: @@ -62,6 +64,6 @@ script: # The scripts for grunt/phpunit type tests - if [ $TEST_SUITE == "functional" ]; then dev/tests/functional/vendor/phpunit/phpunit/phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - #- if [ $TEST_SUITE == "api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE/phpunit_graphql.xml.dist; fi + - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js"] && [ $TEST_SUITE != "api" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - if [ $TEST_SUITE == "js" ]; then grunt $GRUNT_COMMAND; fi + - if [ $TEST_SUITE == "api-functional" ]; then phpunit -c dev/tests/api-functional; fi diff --git a/dev/tests/api-functional/phpunit.xml.dist b/dev/tests/api-functional/phpunit.xml.dist deleted file mode 100644 index a55531aba87e2..0000000000000 --- a/dev/tests/api-functional/phpunit.xml.dist +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- -/** - * PHPUnit configuration for GraphQL web API functional tests. - * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.2/phpunit.xsd" - colors="true" - columns="max" - beStrictAboutTestsThatDoNotTestAnything="false" - bootstrap="./framework/bootstrap.php" -> - <!-- Test suites definition --> - <testsuites> - <testsuite name="Magento GraphQL web API functional tests"> - <directory suffix="Test.php">testsuite/Magento/GraphQl</directory> - </testsuite> - </testsuites> - - <!-- PHP INI settings and constants definition --> - <php> - <includePath>./testsuite</includePath> - <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/> - <const name="TESTS_GLOBAL_CONFIG_FILE" value="config/config-global.php"/> - <!-- Webserver URL --> - <const name="TESTS_BASE_URL" value="http://magento2.travis"/> - <!-- Webserver API user --> - <const name="TESTS_WEBSERVICE_USER" value="admin"/> - <!-- Webserver API key --> - <const name="TESTS_WEBSERVICE_APIKEY" value="123123q"/> - <!-- Define if debugger should be started using XDEBUG_SESSION cookie --> - <const name="TESTS_XDEBUG_ENABLED" value="false"/> - <!-- Define XDEBUG_SESSION cookie value--> - <const name="TESTS_XDEBUG_SESSION" value="phpstorm" /> - - <ini name="date.timezone" value="America/Los_Angeles"/> - - <!-- Semicolon-separated 'glob' patterns, that match global XML configuration files --> - <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> - <!-- Whether to cleanup the application before running tests or not --> - <const name="TESTS_CLEANUP" value="enabled"/> - <!--Defines if Magento should be installed before tests execution--> - <const name="TESTS_MAGENTO_INSTALLATION" value="disabled"/> - <!-- Magento mode for tests execution. Possible values are "default", "developer" and "production". --> - <const name="TESTS_MAGENTO_MODE" value="production"/> - </php> - - <!-- Test listeners --> - <listeners> - <listener class="Magento\TestFramework\Event\PhpUnit"/> - </listeners> -</phpunit> diff --git a/dev/tests/api-functional/phpunit_graphql.xml.dist b/dev/tests/api-functional/phpunit_graphql.xml.dist index 955a3a8953fa8..4a57c338ca3a2 100644 --- a/dev/tests/api-functional/phpunit_graphql.xml.dist +++ b/dev/tests/api-functional/phpunit_graphql.xml.dist @@ -27,7 +27,7 @@ <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/> <const name="TESTS_GLOBAL_CONFIG_FILE" value="config/config-global.php"/> <!-- Webserver URL --> - <const name="TESTS_BASE_URL" value="http://magento2.travis"/> + <const name="TESTS_BASE_URL" value="http://magento.url"/> <!-- Webserver API user --> <const name="TESTS_WEBSERVICE_USER" value="admin"/> <!-- Webserver API key --> diff --git a/dev/travis/before_install.sh b/dev/travis/before_install.sh index c9302f3b6672c..22d6c04dabda4 100755 --- a/dev/travis/before_install.sh +++ b/dev/travis/before_install.sh @@ -34,7 +34,7 @@ if [ $TEST_SUITE == "js" ]; then yarn global add grunt-cli fi -if [ $TEST_SUITE = "functional" ]; then +if [ $TEST_SUITE = "functional" or $TEST_SUITE = "api-functional" ]; then # Install apache sudo apt-get update sudo apt-get install apache2 libapache2-mod-fastcgi diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 1dccc310c7a20..c27e65d3897c7 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -132,6 +132,35 @@ case $TEST_SUITE in php -f generate/moduleSequence.php php -f mtf troubleshooting:check-all + cd ../../.. + ;; + + api-functional) + echo "Installing Magento" + mysql -uroot -e 'CREATE DATABASE magento2;' + php bin/magento setup:install -q \ + --language="en_US" \ + --timezone="UTC" \ + --currency="USD" \ + --base-url="http://${MAGENTO_HOST_NAME}/" \ + --admin-firstname="John" \ + --admin-lastname="Doe" \ + --backend-frontname="backend" \ + --admin-email="admin@example.com" \ + --admin-user="admin" \ + --use-rewrites=1 \ + --admin-use-security-key=0 \ + --admin-password="123123q" + + echo "Enabling production mode" + php bin/magento deploy:mode:set production + + echo "Prepare api-functional tests for running" + cd dev/tests/api-functional + + cp ./phpunit_graphql.xml.dist ./phpunit.xml + sed -e "s?magento.url?${MAGENTO_HOST_NAME}?g" --in-place ./phpunit.xml + cd ../../.. ;; esac From 599cf87a2c7a7eabce65e482557dcfa8f649874c Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 16 Oct 2018 13:19:47 +0200 Subject: [PATCH 327/812] Condition fix for before_install script --- dev/travis/before_install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/travis/before_install.sh b/dev/travis/before_install.sh index 22d6c04dabda4..44ba3fd8b74f1 100755 --- a/dev/travis/before_install.sh +++ b/dev/travis/before_install.sh @@ -34,7 +34,7 @@ if [ $TEST_SUITE == "js" ]; then yarn global add grunt-cli fi -if [ $TEST_SUITE = "functional" or $TEST_SUITE = "api-functional" ]; then +if [ $TEST_SUITE = "functional" ] || [ $TEST_SUITE = "api-functional" ]; then # Install apache sudo apt-get update sudo apt-get install apache2 libapache2-mod-fastcgi From 09e70057d810aa7004f7760b084d16b4833936b1 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 16 Oct 2018 13:27:48 +0200 Subject: [PATCH 328/812] Test api-functional tests alongside with other tests --- .travis.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 930172a9ea6e0..f5a25bc63543d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,14 +25,14 @@ env: - NODE_JS_VERSION=8 - MAGENTO_HOST_NAME="magento2.travis" matrix: -# - TEST_SUITE=unit -# - TEST_SUITE=static -# - TEST_SUITE=js GRUNT_COMMAND=spec -# - TEST_SUITE=js GRUNT_COMMAND=static -# - TEST_SUITE=integration INTEGRATION_INDEX=1 -# - TEST_SUITE=integration INTEGRATION_INDEX=2 -# - TEST_SUITE=integration INTEGRATION_INDEX=3 -# - TEST_SUITE=functional + - TEST_SUITE=unit + - TEST_SUITE=static + - TEST_SUITE=js GRUNT_COMMAND=spec + - TEST_SUITE=js GRUNT_COMMAND=static + - TEST_SUITE=integration INTEGRATION_INDEX=1 + - TEST_SUITE=integration INTEGRATION_INDEX=2 + - TEST_SUITE=integration INTEGRATION_INDEX=3 + - TEST_SUITE=functional - TEST_SUITE=api-functional matrix: exclude: From 1f05fd8b259b94f272d9c44ae147c5df7910e9ff Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <mikalai_shostka@epam.com> Date: Tue, 16 Oct 2018 14:46:29 +0300 Subject: [PATCH 329/812] MAGETWO-95445: Category Flat Data indexer doesnt show status as reindex required after deleting store/storeview - Delete abandoned tables in full reindex --- .../Catalog/Helper/Product/Flat/Indexer.php | 32 +++++++++++++++++++ .../Indexer/Category/Flat/Action/Full.php | 31 +++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php b/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php index 93eaa23b89f16..0366e01ee86ea 100644 --- a/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php +++ b/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php @@ -466,6 +466,17 @@ public function getFlatTableName($storeId) return sprintf('%s_%s', $this->getTable('catalog_product_flat'), $storeId); } + /** + * Retrieve Catalog Product Flat Table name + * + * @param int $storeId + * @return string + */ + private function getCategoryFlatTableName(int $storeId): string + { + return sprintf('%s_store_%s', $this->getTable('catalog_category_flat'), $storeId); + } + /** * Retrieve loaded attribute by code * @@ -515,4 +526,25 @@ public function deleteAbandonedStoreFlatTables() $connection->dropTable($table); } } + + /** + * Delete all category flat tables for not existing stores + * + * @return void + */ + public function deleteAbandonedStoreCategoryFlatTables() + { + $connection = $this->_resource->getConnection(); + $existentTables = $connection->getTables($connection->getTableName('catalog_category_flat_store_%')); + $actualStoreTables = []; + foreach ($this->_storeManager->getStores() as $store) { + $actualStoreTables[] = $this->getCategoryFlatTableName($store->getId()); + } + + $tablesToDelete = array_diff($existentTables, $actualStoreTables); + + foreach ($tablesToDelete as $table) { + $connection->dropTable($table); + } + } } diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php index 64a8f930d83ee..c1e6decf6afef 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php @@ -5,6 +5,11 @@ */ namespace Magento\Catalog\Model\Indexer\Category\Flat\Action; +use Magento\Framework\App\ResourceConnection; + +/** + * Class for full reindex flat categories + */ class Full extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction { /** @@ -19,6 +24,28 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction */ protected $allowTableChanges = true; + /** + * @var \Magento\Catalog\Helper\Product\Flat\Indexer + */ + private $indexer; + + /** + * @param ResourceConnection $resource + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper + * @param \Magento\Catalog\Helper\Product\Flat\Indexer $indexer + */ + public function __construct( + ResourceConnection $resource, + \Magento\Store\Model\StoreManagerInterface $storeManager, + \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, + \Magento\Catalog\Helper\Product\Flat\Indexer $indexer = null + ) { + $this->indexer = $indexer ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Catalog\Helper\Product\Flat\Indexer::class); + parent::__construct($resource, $storeManager, $resourceHelper); + } + /** * Add suffix to table name to show it is old * @@ -92,6 +119,7 @@ protected function populateFlatTables(array $stores) /** * Create table and add attributes as fields for specified store. + * * This routine assumes that DDL operations are allowed * * @param int $store @@ -109,6 +137,7 @@ protected function createTable($store) /** * Create category flat tables and add attributes as fields. + * * Tables are created only if DDL operations are allowed * * @param \Magento\Store\Model\Store[] $stores if empty, create tables for all stores of the application @@ -182,7 +211,7 @@ public function reindexAll() $stores = $this->storeManager->getStores(); $this->populateFlatTables($stores); $this->switchTables($stores); - + $this->indexer->deleteAbandonedStoreCategoryFlatTables(); $this->allowTableChanges = true; return $this; From e3fc117bfa5158b51c875e76461539aba5b2b6a7 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 16 Oct 2018 15:33:43 +0300 Subject: [PATCH 330/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- app/code/Magento/Catalog/etc/adminhtml/system.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml index 74661acb8f136..1b0fe4c85f617 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/system.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml @@ -206,7 +206,7 @@ <label>Images Upload Configuration</label> <field id="jpeg_quality" translate="label comment" type="text" sortOrder="100" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Quality</label> - <validate>validate-greater-than-zero validate-number required-entry digits-range-1-100</validate> + <validate>validate-greater-than-zero validate-digits validate-range required-entry digits-range-1-100</validate> <comment>Jpeg quality for resized images 1-100%.</comment> </field> </group> From 11290c5d74cb2a9878735fac7dd4648d1923f71c Mon Sep 17 00:00:00 2001 From: anuj <anuj.gupta701@webkul.com> Date: Tue, 16 Oct 2018 18:42:50 +0530 Subject: [PATCH 331/812] issue #18618 fixed --- app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php index bb190260e4776..5059d61eb3f7e 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php @@ -123,7 +123,8 @@ protected function _prepareColumns() 'header' => __('Order Total'), 'index' => 'grand_total', 'type' => 'currency', - 'currency' => 'order_currency_code' + 'currency' => 'order_currency_code', + 'rate' => 1 ] ); From 2f9b761f368b925dc6563e3c6e791425005286a3 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Tue, 16 Oct 2018 10:27:21 -0500 Subject: [PATCH 332/812] MAGETWO-95259: CatalogSearch module deprecation must be reverted --- .../Framework/Indexer/IndexStructure.php | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/internal/Magento/Framework/Indexer/IndexStructure.php b/lib/internal/Magento/Framework/Indexer/IndexStructure.php index c9376f00b711e..a39de2d5b8a62 100644 --- a/lib/internal/Magento/Framework/Indexer/IndexStructure.php +++ b/lib/internal/Magento/Framework/Indexer/IndexStructure.php @@ -13,6 +13,12 @@ use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver; use Magento\Framework\Search\Request\Dimension; +/** + * Full text search index structure. + * + * @deprecated + * @see \Magento\ElasticSearch + */ class IndexStructure implements IndexStructureInterface { /** @@ -58,9 +64,7 @@ public function __construct( } /** - * @param string $index - * @param Dimension[] $dimensions - * @return void + * @inheritdoc */ public function delete($index, array $dimensions = []) { @@ -69,10 +73,7 @@ public function delete($index, array $dimensions = []) } /** - * @param string $index - * @param array $fields - * @param Dimension[] $dimensions - * @return void + * @inheritdoc */ public function create($index, array $fields, array $dimensions = []) { @@ -83,6 +84,8 @@ public function create($index, array $fields, array $dimensions = []) } /** + * Create full text index. + * * @param string $tableName * @throws \Zend_Db_Exception * @return void @@ -94,6 +97,8 @@ protected function createFulltextIndex($tableName) } /** + * Configure full text index table. + * * @param Table $table * @return Table */ @@ -129,6 +134,8 @@ protected function configureFulltextTable(Table $table) } /** + * Create flat index. + * * @param string $tableName * @param array $fields * @throws \Zend_Db_Exception @@ -160,6 +167,8 @@ protected function createFlatIndex($tableName, array $fields) } /** + * Drop table. + * * @param AdapterInterface $connection * @param string $tableName * @return void From 11b4c70bb1807e1db9703f8b0fa241de9790e512 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Tue, 16 Oct 2018 11:10:29 -0500 Subject: [PATCH 333/812] MAGETWO-95723: Product Review "Save and Next" and "Save and Previous" not working - Fixed query ordering - Added test coverage --- .../Review/Product/Collection.php | 1 - .../Review/Product/CollectionTest.php | 73 ++++++++++++++++++- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php index 99c963501a9d4..68dc8d753b5bd 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php +++ b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php @@ -406,7 +406,6 @@ public function getResultingIds() $idsSelect->reset(Select::LIMIT_COUNT); $idsSelect->reset(Select::LIMIT_OFFSET); $idsSelect->reset(Select::COLUMNS); - $idsSelect->reset(Select::ORDER); $idsSelect->columns('rt.review_id'); return $this->getConnection()->fetchCol($idsSelect); } diff --git a/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php index a7f859b23dfa2..39129dee28c7c 100644 --- a/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php @@ -3,20 +3,85 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Review\Model\ResourceModel\Review\Product; class CollectionTest extends \PHPUnit\Framework\TestCase { /** + * @param string $status + * @param int $expectedCount + * @param string $sortAttribute + * @param string $dir + * @param callable $assertion + * @dataProvider sortOrderAssertionsDataProvider * @magentoDataFixture Magento/Review/_files/different_reviews.php */ - public function testGetResultingIds() - { + public function testGetResultingIds( + ?string $status, + int $expectedCount, + string $sortAttribute, + string $dir, + callable $assertion + ) { + /** + * @var $collection \Magento\Review\Model\ResourceModel\Review\Product\Collection + */ $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( \Magento\Review\Model\ResourceModel\Review\Product\Collection::class ); - $collection->addStatusFilter(\Magento\Review\Model\Review::STATUS_APPROVED); + if ($status) { + $collection->addStatusFilter($status); + } + $collection->setOrder($sortAttribute, $dir); $actual = $collection->getResultingIds(); - $this->assertCount(2, $actual); + $this->assertCount($expectedCount, $actual); + $assertion($actual); + } + + /** + * @return array + */ + public function sortOrderAssertionsDataProvider() :array + { + return [ + [ + \Magento\Review\Model\Review::STATUS_APPROVED, + 2, + 'rt.review_id', + 'DESC', + function (array $actual) :void { + $this->assertLessThan($actual[0], $actual[1]); + } + ], + [ + \Magento\Review\Model\Review::STATUS_APPROVED, + 2, + 'rt.review_id', + 'ASC', + function (array $actual) :void { + $this->assertLessThan($actual[1], $actual[0]); + } + ], + [ + \Magento\Review\Model\Review::STATUS_APPROVED, + 2, + 'rt.created_at', + 'ASC', + function (array $actual) :void { + $this->assertLessThan($actual[1], $actual[0]); + } + ], + [ + null, + 3, + 'rt.review_id', + 'ASC', + function (array $actual) :void { + $this->assertLessThan($actual[1], $actual[0]); + } + ] + ]; } } From 21fdaddba19cb329b58b6ee2efb74cb2298049ce Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 16 Oct 2018 12:09:57 -0500 Subject: [PATCH 334/812] MAGETWO-94962: Unable to set default option for swatch attribute --- .../Catalog/Test/Handler/CatalogProductAttribute/Curl.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php index 7ecaeb5ea7b82..3d644a2a32274 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php @@ -144,6 +144,10 @@ public function persist(FixtureInterface $fixture = null) */ protected function changeStructureOfTheData(array $data): array { + if (!isset($data['options'])) { + return $data; + } + $serializedOptions = $this->getSerializeOptions($data['options']); if ($serializedOptions) { $data['serialized_options'] = $serializedOptions; From a2c993a58a43db0fe0a51bd1d1b482d7a05f1e8f Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Tue, 16 Oct 2018 12:24:15 -0500 Subject: [PATCH 335/812] MAGETWO-95433: Customer address custom attributes (Multi select, dropdown) display behavior on storefront is not per standards (PFA snap) - make sure multiselect doesn't show background image --- lib/web/css/source/lib/_forms.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/css/source/lib/_forms.less b/lib/web/css/source/lib/_forms.less index b1c7a49da4a7a..531cf3d34ad76 100644 --- a/lib/web/css/source/lib/_forms.less +++ b/lib/web/css/source/lib/_forms.less @@ -288,7 +288,7 @@ .lib-form-element-input(@_type: select); } - select[multiple="multiple"] { + select[multiple] { .lib-css(height, auto); background-image: none; } From 2773aeba9f0b6daeb98c0f2f7326e831d7018cb4 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Tue, 16 Oct 2018 13:13:49 -0500 Subject: [PATCH 336/812] MAGETWO-95259: CatalogSearch module deprecation must be reverted --- .../Model/Search/RequestGenerator/Decimal.php | 7 +++---- .../Model/Search/RequestGenerator/General.php | 7 +++---- .../Search/RequestGenerator/GeneratorInterface.php | 10 ++++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php index ceff0ea2e5d17..b3d39a48fe9fc 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php @@ -11,13 +11,12 @@ use Magento\Framework\Search\Request\FilterInterface; /** - * @deprecated - * @see \Magento\ElasticSearch + * Catalog search range request generator. */ class Decimal implements GeneratorInterface { /** - * {@inheritdoc} + * @inheritdoc */ public function getFilterData(Attribute $attribute, $filterName) { @@ -31,7 +30,7 @@ public function getFilterData(Attribute $attribute, $filterName) } /** - * {@inheritdoc} + * @inheritdoc */ public function getAggregationData(Attribute $attribute, $bucketName) { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php index 4321105a7e8fd..63b09de7f08d8 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php @@ -11,13 +11,12 @@ use Magento\Framework\Search\Request\FilterInterface; /** - * @deprecated - * @see \Magento\ElasticSearch + * Catalog search request generator. */ class General implements GeneratorInterface { /** - * {@inheritdoc} + * @inheritdoc */ public function getFilterData(Attribute $attribute, $filterName) { @@ -30,7 +29,7 @@ public function getFilterData(Attribute $attribute, $filterName) } /** - * {@inheritdoc} + * @inheritdoc */ public function getAggregationData(Attribute $attribute, $bucketName) { diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php index 863f1fb7466c9..22f829063fbe7 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php @@ -9,15 +9,16 @@ use Magento\Catalog\Model\ResourceModel\Eav\Attribute; /** + * Catalog search reguest generator interface. + * * @api * @since 100.1.6 - * @deprecated - * @see \Magento\ElasticSearch */ interface GeneratorInterface { /** - * Get filter data for specific attribute + * Get filter data for specific attribute. + * * @param Attribute $attribute * @param string $filterName * @return array @@ -26,7 +27,8 @@ interface GeneratorInterface public function getFilterData(Attribute $attribute, $filterName); /** - * Get aggregation data for specific attribute + * Get aggregation data for specific attribute. + * * @param Attribute $attribute * @param string $bucketName * @return array From bd6c51afe863e05111a6b4da8e095a3341d67a12 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Tue, 16 Oct 2018 14:42:05 -0500 Subject: [PATCH 337/812] MAGETWO-95483: Can't delete a cart entry when the cart has a shipping address - Fixed static error --- .../Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php b/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php index 4f05279350a7c..e7776b3dcbedc 100644 --- a/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php +++ b/app/code/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddresses.php @@ -15,10 +15,11 @@ class ResetQuoteAddresses { /** + * Clears the quote addresses when all the items are removed from the cart + * * @param Quote $quote * @param Quote $result * @param mixed $itemId - * * @return Quote * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ From 7ca8b43efd55e431feea791f56c9ecd1d8e8d9b2 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Tue, 16 Oct 2018 22:40:54 -0500 Subject: [PATCH 338/812] MAGETWO-95532: Unable to upload image from TinyMCE3 - added step to check if config tab for wysiwyg is opened --- .../Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 2 +- .../Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 5ae3f4af2421e..84bc3865a008e 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -19,7 +19,7 @@ <testCaseId value="MAGETWO-95725"/> </annotations> <before> - <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> <!-- Choose TinyMCE3 as the default WYSIWYG editor--> <actionGroup ref="SwitchToTinyMCE3" stepKey="switchToTinyMCE3"/> diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml index 836cba95a6d00..2d784842ea46a 100644 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml @@ -21,6 +21,7 @@ </actionGroup> <actionGroup name="SwitchToTinyMCE3"> <comment userInput="Choose TinyMCE3 as the default editor" stepKey="chooseTinyMCE3AsEditor"/> + <conditionalClick stepKey="expandWYSIWYGOptions1" selector="{{ContentManagementSection.WYSIWYGOptions}}" dependentSelector="{{ContentManagementSection.CheckIfTabExpand}}" visible="true" /> <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox2" /> <uncheckOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="uncheckUseSystemValue2"/> <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown2" /> From 85961ca8e08b488d7efd4cfd12bbb540af0dea59 Mon Sep 17 00:00:00 2001 From: vgelani <vishalgelani99@gmail.com> Date: Wed, 17 Oct 2018 14:46:54 +0530 Subject: [PATCH 339/812] Fixed class name issue in comment --- app/code/Magento/AdminNotification/Block/Window.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/AdminNotification/Block/Window.php b/app/code/Magento/AdminNotification/Block/Window.php index 9563626ee2577..90a0a1d21d865 100644 --- a/app/code/Magento/AdminNotification/Block/Window.php +++ b/app/code/Magento/AdminNotification/Block/Window.php @@ -40,7 +40,7 @@ class Window extends \Magento\Backend\Block\Template protected $_criticalCollection; /** - * @var \Magento\Adminnotification\Model\Inbox + * @var \Magento\AdminNotification\Model\Inbox */ protected $_latestItem; @@ -92,7 +92,7 @@ protected function _toHtml() /** * Retrieve latest critical item * - * @return bool|\Magento\Adminnotification\Model\Inbox + * @return bool|\Magento\AdminNotification\Model\Inbox */ protected function _getLatestItem() { From 10d4a59cf31fce794b2ac3d2ddd12eea16a1f43e Mon Sep 17 00:00:00 2001 From: Sven Reichel <github-sr@hotmail.com> Date: Wed, 17 Oct 2018 15:26:34 +0200 Subject: [PATCH 340/812] Remove unnecessary class import, see #18117 --- app/code/Magento/Customer/Model/GroupManagement.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Model/GroupManagement.php b/app/code/Magento/Customer/Model/GroupManagement.php index eb5d90f2fd7ea..48cb5d55061c5 100644 --- a/app/code/Magento/Customer/Model/GroupManagement.php +++ b/app/code/Magento/Customer/Model/GroupManagement.php @@ -15,7 +15,6 @@ use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\ObjectManager; -use Magento\Framework\Data\Collection; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Store\Model\StoreManagerInterface; @@ -170,7 +169,7 @@ public function getLoggedInGroups() ->create(); $groupNameSortOrder = $this->sortOrderBuilder ->setField('customer_group_code') - ->setDirection(Collection::SORT_ORDER_ASC) + ->setAscendingDirection() ->create(); $searchCriteria = $this->searchCriteriaBuilder ->addFilters($notLoggedInFilter) From 1c7c6fbf4ca26a5518634ecfec919aba3593e0c6 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 17 Oct 2018 17:09:36 +0300 Subject: [PATCH 341/812] MAGETWO-90021: [Catalog] ProductAttributeMediaGalleryManagementInterface removes product from index, impossible to restore - Change code back as there are no changes in 2.3.0 release. --- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) 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 b9993b420f427..167ab91b9d01e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -452,9 +452,7 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() } short_description sku - small_image { - path - } + small_image small_image_label special_from_date special_price @@ -485,7 +483,7 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() QUERY; $response = $this->graphQlQuery($query); - + /** * @var ProductRepositoryInterface $productRepository */ From 84dc7dc461031f5f73a38ec952c59ae4407a9cab Mon Sep 17 00:00:00 2001 From: Yurii Borysov <yurii_borysov@epam.com> Date: Wed, 17 Oct 2018 17:49:28 +0300 Subject: [PATCH 342/812] MAGETWO-95614: Client side less compilation doesn't work properly (Page UI breaks) - Fixed !important in variable declaration that broke the client side less compilation --- .../blank/Magento_Swatches/web/css/source/_module.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less index b5d604597148a..fb10c175e3c36 100644 --- a/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less @@ -26,7 +26,7 @@ @swatch-option-text__background: @swatch-option__background; @swatch-option-text__color: #686868; -@swatch-option-text__selected__background-color: @color-white !important; +@swatch-option-text__selected__background-color: @color-white; // Size and Manufacturer attributes @attr-swatch-option__background: @swatch-option__background; @@ -143,7 +143,7 @@ margin-right: 7px; &.selected { - .lib-css(background-color, @swatch-option-text__selected__background-color); + .lib-css(background-color, @swatch-option-text__selected__background-color) !important; } } From e24d8b96d4c41454bcaccfd6ed4105751905d0a8 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 17 Oct 2018 10:46:41 -0500 Subject: [PATCH 343/812] Fix Value model description --- lib/internal/Magento/Framework/App/Config/Value.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index e6923caa3d28c..7ba4225ce2fb8 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -8,6 +8,10 @@ /** * Config data model * + * This model is temporarily marked as API since {@see \Magento\Framework\App\Config\ValueInterface} doesn't fit + * developers' needs of extensibility. In 2.4 we are going to introduce a new iterface which should cover all needs + * and deprecate the mentioned together with the model + * * @method string getScope() * @method \Magento\Framework\App\Config\ValueInterface setScope(string $value) * @method int getScopeId() From 863f772a07a5628d593e971a8df9b3f68b5a7b5a Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 17 Oct 2018 10:49:41 -0500 Subject: [PATCH 344/812] Remove API annotiotion --- lib/internal/Magento/Framework/App/Config/ValueInterface.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index ab6a34c4274bd..37e821f026869 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -9,7 +9,10 @@ /** * Interface \Magento\Framework\App\Config\ValueInterface - * @api + * + * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going + * to introduce a new iterface which should cover all needs and deprecate the this one with the model + * {@see \Magento\Framework\App\Config\Value} */ interface ValueInterface { From 78454931b700d33b1319a5c689597533a1f22ad8 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Wed, 17 Oct 2018 10:49:55 -0500 Subject: [PATCH 345/812] MAGETWO-95501: Checkout page does not provide shipping methods option on cloud env --- .../view/frontend/web/js/model/error-processor.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js b/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js index 848a7daf71e1b..86d6c4dd10580 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js @@ -8,8 +8,9 @@ */ define([ 'mage/url', - 'Magento_Ui/js/model/messageList' -], function (url, globalMessageList) { + 'Magento_Ui/js/model/messageList', + 'mage/translate' +], function (url, globalMessageList, $t) { 'use strict'; return { @@ -25,7 +26,11 @@ define([ if (response.status == 401) { //eslint-disable-line eqeqeq window.location.replace(url.build('customer/account/login/')); } else { - error = JSON.parse(response.responseText); + try { + error = JSON.parse(response.responseText); + } catch (exception) { + error = $t('Something went wrong with your request. Please try again later.') + } messageContainer.addErrorMessage(error); } } From 34e1041c95169e2fff9fdc3a65b21779bc8243c5 Mon Sep 17 00:00:00 2001 From: Navarr Barnier <navarr@mediotype.com> Date: Tue, 31 Jul 2018 12:43:37 -0500 Subject: [PATCH 346/812] Add Value and ValueInterface to Magento Framework's public API These classes are necessary/useful for creating a backend source for a Magento Configuration field. As such they should be reliable and part of the public API. --- lib/internal/Magento/Framework/App/Config/Value.php | 2 ++ lib/internal/Magento/Framework/App/Config/ValueInterface.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index c85b484d51ce2..e6923caa3d28c 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -17,6 +17,8 @@ * @method string getValue() * @method \Magento\Framework\App\Config\ValueInterface setValue(string $value) * + * @api + * * @SuppressWarnings(PHPMD.NumberOfChildren) */ class Value extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\App\Config\ValueInterface diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index 1e0747acc36f2..ab6a34c4274bd 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -9,7 +9,7 @@ /** * Interface \Magento\Framework\App\Config\ValueInterface - * + * @api */ interface ValueInterface { From 918c9c28e6d32ed40f353171d00a608350389b68 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 17 Oct 2018 10:46:41 -0500 Subject: [PATCH 347/812] Fix Value model description --- lib/internal/Magento/Framework/App/Config/Value.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index e6923caa3d28c..7ba4225ce2fb8 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -8,6 +8,10 @@ /** * Config data model * + * This model is temporarily marked as API since {@see \Magento\Framework\App\Config\ValueInterface} doesn't fit + * developers' needs of extensibility. In 2.4 we are going to introduce a new iterface which should cover all needs + * and deprecate the mentioned together with the model + * * @method string getScope() * @method \Magento\Framework\App\Config\ValueInterface setScope(string $value) * @method int getScopeId() From 15d448d79b5ff721cda472a57e34ea791742dc53 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 17 Oct 2018 10:49:41 -0500 Subject: [PATCH 348/812] Remove API annotiotion --- lib/internal/Magento/Framework/App/Config/ValueInterface.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index ab6a34c4274bd..37e821f026869 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -9,7 +9,10 @@ /** * Interface \Magento\Framework\App\Config\ValueInterface - * @api + * + * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going + * to introduce a new iterface which should cover all needs and deprecate the this one with the model + * {@see \Magento\Framework\App\Config\Value} */ interface ValueInterface { From de5a0d340123db78d95e72a5c6bf648a707fb454 Mon Sep 17 00:00:00 2001 From: Navarr Barnier <navarr@mediotype.com> Date: Tue, 31 Jul 2018 15:23:40 -0500 Subject: [PATCH 349/812] Add ReadFactory and WriteFactory to Magento's public API These classes are necessary/useful for creating instances of ReadInterface and WriteInterface using the public API. --- .../Magento/Framework/Filesystem/File/ReadFactory.php | 6 +++++- .../Magento/Framework/Filesystem/File/WriteFactory.php | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php b/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php index 38b581da752b7..5d9badf42073f 100644 --- a/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php +++ b/lib/internal/Magento/Framework/Filesystem/File/ReadFactory.php @@ -8,6 +8,10 @@ use Magento\Framework\Filesystem\DriverInterface; use Magento\Framework\Filesystem\DriverPool; +/** + * Opens a file for reading + * @api + */ class ReadFactory { /** @@ -28,7 +32,7 @@ public function __construct(DriverPool $driverPool) } /** - * Create a readable file + * Create a {@see ReaderInterface} * * @param string $path * @param DriverInterface|string $driver Driver or driver code diff --git a/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php b/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php index a45d6a62488f6..af2a43ceaedc3 100644 --- a/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php +++ b/lib/internal/Magento/Framework/Filesystem/File/WriteFactory.php @@ -8,6 +8,10 @@ use Magento\Framework\Filesystem\DriverInterface; use Magento\Framework\Filesystem\DriverPool; +/** + * Opens a file for reading and/or writing + * @api + */ class WriteFactory extends ReadFactory { /** @@ -29,12 +33,12 @@ public function __construct(DriverPool $driverPool) } /** - * Create a readable file. + * Create a {@see WriterInterface} * * @param string $path * @param DriverInterface|string $driver Driver or driver code * @param string $mode [optional] - * @return Write + * @return WriteInterface */ public function create($path, $driver, $mode = 'r') { From f67b94f3b424811fe57ef4e280d6724acbce3e90 Mon Sep 17 00:00:00 2001 From: Navarr Barnier <navarr@mediotype.com> Date: Tue, 31 Jul 2018 15:30:23 -0500 Subject: [PATCH 350/812] Add directory WriteInterface and ReadInterface --- .../Magento/Framework/Filesystem/Directory/ReadInterface.php | 2 +- .../Magento/Framework/Filesystem/Directory/WriteInterface.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php b/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php index 5519245ec24b4..61108c64dda44 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/ReadInterface.php @@ -7,7 +7,7 @@ /** * Interface \Magento\Framework\Filesystem\Directory\ReadInterface - * + * @api */ interface ReadInterface { diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php b/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php index c72651a78dad3..186cbcb81bff2 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/WriteInterface.php @@ -7,7 +7,7 @@ /** * Interface \Magento\Framework\Filesystem\Directory\WriteInterface - * + * @api */ interface WriteInterface extends ReadInterface { From 1fdf2556c386703f597be3921285b45e43789cb1 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 17 Oct 2018 12:31:09 -0500 Subject: [PATCH 351/812] MAGETWO-95501: Checkout page does not provide shipping methods option on cloud env --- .../frontend/web/js/model/error-processor.js | 2 +- .../frontend/js/model/error-processor.test.js | 70 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js b/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js index 86d6c4dd10580..42b692ff9dd8d 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js @@ -29,7 +29,7 @@ define([ try { error = JSON.parse(response.responseText); } catch (exception) { - error = $t('Something went wrong with your request. Please try again later.') + error = $t('Something went wrong with your request. Please try again later.'); } messageContainer.addErrorMessage(error); } diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js new file mode 100644 index 0000000000000..3a6cd6d60d38b --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js @@ -0,0 +1,70 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/*eslint max-nested-callbacks: 0*/ +define([ + 'squire' +], function (Squire) { + 'use strict'; + + describe('Magento_Checkout/js/model/error-processor', function () { + var injector = new Squire(), + mocks = { + 'mage/url': { + /** Method stub. */ + build: jasmine.createSpy() + } + }, + model; + + beforeEach(function (done) { + injector.mock(mocks); + injector.require([ + 'Magento_Checkout/js/model/error-processor' + ], function (processor) { + model = processor; + + done(); + }); + }); + + describe('Check process method', function () { + it('check on success response with valid response data', function () { + var messageObject = { + message: 'Valid error message!' + }, + messageContainer = jasmine.createSpyObj('globalMessageList', ['addErrorMessage']); + + model.process({ + status: 200, + responseText: JSON.stringify(messageObject) + }, messageContainer); + expect(messageContainer.addErrorMessage).toHaveBeenCalledWith(messageObject); + }); + + it('check on success response with invalid response data', function () { + var messageContainer = jasmine.createSpyObj('globalMessageList', ['addErrorMessage']); + + model.process({ + status: 200, + responseText: '' + }, messageContainer); + expect(messageContainer.addErrorMessage) + .toHaveBeenCalledWith('Something went wrong with your request. Please try again later.'); + }); + + it('check on failed status', function () { + var messageContainer = jasmine.createSpyObj('globalMessageList', ['addErrorMessage']); + + model.process({ + status: 401, + responseText: '' + }, messageContainer); + expect(mocks['mage/url'].build) + .toHaveBeenCalled(); + }); + }); + }); +}); From 75ebeaf1c7e8beb7a6ec2ccb34c1f4df6e1fc544 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 17 Oct 2018 13:07:08 -0500 Subject: [PATCH 352/812] MAGETWO-95723: Product Review "Save and Next" and "Save and Previous" not working - Added test class description --- .../Model/ResourceModel/Review/Product/CollectionTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php index 39129dee28c7c..559c62e42dec3 100644 --- a/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php @@ -7,6 +7,9 @@ namespace Magento\Review\Model\ResourceModel\Review\Product; +/** + * Tests some functionality of the Product Review collection + */ class CollectionTest extends \PHPUnit\Framework\TestCase { /** From dd4cc952ed9de82968deaac2f74c439e0b867bcd Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Wed, 17 Oct 2018 13:12:23 -0500 Subject: [PATCH 353/812] MAGETWO-95532: Unable to upload image from TinyMCE3 - fix build failure --- .../Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 84bc3865a008e..04115ccdcc480 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -28,7 +28,7 @@ <!-- Switch WYSIWYG editor to TinyMCE4--> <comment userInput="Reset editor as TinyMCE4" stepKey="chooseTinyMCE4AsEditor"/> <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4"/> - <actionGroup ref="logout" stepKey="logOut"/> + <actionGroup ref="logout" stepKey="logout"/> </after> <amOnPage url="{{CmsNewPagePage.url}}" stepKey="navigateToPage2"/> <waitForPageLoad stepKey="wait5"/> From 03f4abc29263fdd9a269d381de8c14c4dc455042 Mon Sep 17 00:00:00 2001 From: duhon <duhon@rambler.ru> Date: Wed, 17 Oct 2018 21:04:02 +0300 Subject: [PATCH 354/812] MAGETWO-95652: Call to \Magento\Framework\Api\MetadataServiceInterface::getCustomAttributesMetadata leads to fatal error --- app/code/Magento/Catalog/Model/Product.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index a488e306473b2..9f8d1786334f2 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -500,7 +500,7 @@ protected function _getResource() /** * Get a list of custom attribute codes that belongs to product attribute set. * - * If attribute set not specified fors product will return all product attribute codes + * If attribute set not specified for product will return all product attribute codes * * @return string[] */ From 365331a281be8d823fead594addfad777877a8a2 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 17 Oct 2018 13:42:28 -0500 Subject: [PATCH 355/812] ENGCOM-3214: Add Value, ReadFactory and WriteFactory to Magento Framework's public API --- lib/internal/Magento/Framework/App/Config/Value.php | 4 ++-- lib/internal/Magento/Framework/App/Config/ValueInterface.php | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index 7ba4225ce2fb8..23fe71aa6685e 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -113,7 +113,7 @@ public function getFieldsetDataValue($key) } /** - * {@inheritdoc} + * Processing object after save data * * {@inheritdoc}. In addition, it sets status 'invalidate' for config caches * @@ -129,7 +129,7 @@ public function afterSave() } /** - * {@inheritdoc} + * Processing object after delete data * * {@inheritdoc}. In addition, it sets status 'invalidate' for config caches * diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index 37e821f026869..5468caf4902f3 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -9,8 +9,8 @@ /** * Interface \Magento\Framework\App\Config\ValueInterface - * - * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going + * + * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going * to introduce a new iterface which should cover all needs and deprecate the this one with the model * {@see \Magento\Framework\App\Config\Value} */ @@ -23,6 +23,7 @@ interface ValueInterface /** * Check if config data value was changed + * * @todo this method should be make as protected * @return bool */ From cf23c7d1a52bd6a41828722049975cc3671592c3 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 17 Oct 2018 14:58:52 -0500 Subject: [PATCH 356/812] ENGCOM-3214: Add Value, ReadFactory and WriteFactory to Magento Framework's public API --- .../Magento/Test/Legacy/_files/obsolete_constants.php | 1 - lib/internal/Magento/Framework/App/Config/Value.php | 2 +- lib/internal/Magento/Framework/App/Config/ValueInterface.php | 4 +++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php index cbf499c8dad38..5bcc712be6f74 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php @@ -712,7 +712,6 @@ 'Magento\Sales\Block\Reorder\Sidebar', '\Magento\Sales\CustomerData\LastOrderedItems::SIDEBAR_ORDER_LIMIT', ], - ['ENTITY', 'Magento\Framework\App\Config\ValueInterface'], ['XML_PATH_ALLOW_CURRENCIES_INSTALLED', 'Magento\Framework\Locale\CurrencyInterface'], [ 'DEFAULT_CURRENCY', diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index 23fe71aa6685e..6fde4dded4695 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -9,7 +9,7 @@ * Config data model * * This model is temporarily marked as API since {@see \Magento\Framework\App\Config\ValueInterface} doesn't fit - * developers' needs of extensibility. In 2.4 we are going to introduce a new iterface which should cover all needs + * developers' needs of extensibility. In 2.4 we are going to introduce a new interface which should cover all needs * and deprecate the mentioned together with the model * * @method string getScope() diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index 5468caf4902f3..0aa600b84dcce 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -11,13 +11,15 @@ * Interface \Magento\Framework\App\Config\ValueInterface * * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going - * to introduce a new iterface which should cover all needs and deprecate the this one with the model + * to introduce a new interface which should cover all needs and deprecate the this one with the model * {@see \Magento\Framework\App\Config\Value} */ interface ValueInterface { /** * Table name + * + * @deprecated since it is not used */ const ENTITY = 'config_data'; From b80b12f4588133656752e32908f8a913b1ceac60 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Wed, 17 Oct 2018 14:58:53 -0500 Subject: [PATCH 357/812] MAGETWO-95433: Customer address custom attributes (Multi select, dropdown) display behavior on storefront is not per standards (PFA snap) - fix static test failure --- .../Magento/Catalog/_files/category_duplicates_rollback.php | 1 + .../CatalogImportExport/_files/update_category_duplicates.php | 1 + .../_files/update_category_duplicates_rollback.php | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php index a1dc418e15633..ceaad3a00329f 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_duplicates_rollback.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); use Magento\Framework\Exception\NoSuchEntityException; diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php index 27ca8e7a04413..53d30e834a07d 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); require dirname(dirname(__DIR__)) . '/Catalog/_files/category_duplicates.php'; diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php index f3bb3d0415afa..ca0f379a03dc5 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/update_category_duplicates_rollback.php @@ -3,13 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + require dirname(dirname(__DIR__)) . '/Catalog/_files/category_duplicates_rollback.php'; //Delete products created in CSV import /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ $productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); $csvProductSkus = ['simple1', 'simple2', 'simple3']; -foreach($csvProductSkus as $sku) { +foreach ($csvProductSkus as $sku) { try { $product = $productRepository->get($sku, false, null, true); $productRepository->delete($product); From 2aebcfb64b863e2b15b357ca6b7b1d07299594b4 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <paliarus@adobe.com> Date: Wed, 17 Oct 2018 15:57:10 -0500 Subject: [PATCH 358/812] MAGETWO-95259: CatalogSearch module deprecation must be reverted --- .../CatalogSearch/Block/Advanced/Form.php | 13 +++++++------ .../CatalogSearch/Block/Advanced/Result.php | 16 +++++++++++++++- .../CatalogSearch/Controller/Advanced/Index.php | 5 ++++- .../CatalogSearch/Controller/Advanced/Result.php | 5 ++++- .../CatalogSearch/Controller/Result/Index.php | 3 +++ .../Aggregation/Checker/Query/AdvancedSearch.php | 2 +- .../CatalogSearch/Model/Adapter/Options.php | 4 +++- .../Adminhtml/System/Config/Backend/Engine.php | 3 +++ .../Magento/CatalogSearch/Model/Advanced.php | 3 +++ .../Model/Attribute/SearchWeight.php | 5 +++-- .../Model/Autocomplete/DataProvider.php | 6 +++++- .../Indexer/Fulltext/Action/DataProvider.php | 2 ++ .../Model/Indexer/Fulltext/Plugin/Attribute.php | 3 +++ .../Model/Indexer/Fulltext/Plugin/Category.php | 5 +++++ .../Model/Indexer/Fulltext/Plugin/Product.php | 7 +++++++ .../Model/Indexer/Fulltext/Store.php | 7 +++++++ .../Model/Indexer/IndexStructureFactory.php | 2 ++ .../Model/Indexer/IndexerHandlerFactory.php | 2 ++ .../CatalogSearch/Model/Indexer/Mview/Action.php | 3 +++ .../Layer/Category/ItemCollectionProvider.php | 6 ++++-- .../Model/Layer/Filter/Category.php | 6 ++++-- .../CatalogSearch/Model/Layer/Filter/Price.php | 8 ++++++++ .../Layer/Search/Plugin/CollectionFilter.php | 3 +++ .../Model/Layer/Search/StateKey.php | 6 ++++-- .../CatalogSearch/Model/Price/Interval.php | 11 ++++++++--- .../Model/ResourceModel/Advanced/Collection.php | 8 ++++++++ .../Model/ResourceModel/Fulltext/Collection.php | 16 +++++++++++++++- app/code/Magento/Search/Model/Query.php | 7 +++++-- 28 files changed, 141 insertions(+), 26 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Block/Advanced/Form.php b/app/code/Magento/CatalogSearch/Block/Advanced/Form.php index 4d1957991d1bf..681b7ecfb02dc 100644 --- a/app/code/Magento/CatalogSearch/Block/Advanced/Form.php +++ b/app/code/Magento/CatalogSearch/Block/Advanced/Form.php @@ -4,11 +4,6 @@ * See COPYING.txt for license details. */ -/** - * Advanced search form - * - * @author Magento Core Team <core@magentocommerce.com> - */ namespace Magento\CatalogSearch\Block\Advanced; use Magento\CatalogSearch\Model\Advanced; @@ -21,6 +16,8 @@ use Magento\Framework\View\Element\Template\Context; /** + * Advanced search form + * * @api * @since 100.0.2 */ @@ -58,7 +55,7 @@ public function __construct( } /** - * @return AbstractBlock + * @inheritdoc */ public function _prepareLayout() { @@ -286,6 +283,8 @@ public function getAttributeYesNoElement($attribute) } /** + * Get select block. + * * @return BlockInterface */ protected function _getSelectBlock() @@ -299,6 +298,8 @@ protected function _getSelectBlock() } /** + * Get date block. + * * @return BlockInterface|mixed */ protected function _getDateBlock() diff --git a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php index 7c8e65b249139..9f25990594a49 100644 --- a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php +++ b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php @@ -63,7 +63,7 @@ public function __construct( } /** - * @return AbstractBlock + * @inheritdoc */ protected function _prepareLayout() { @@ -125,6 +125,8 @@ public function setListModes() } /** + * Initialize list collection. + * * @return void */ public function setListCollection() @@ -133,6 +135,8 @@ public function setListCollection() } /** + * Get product collection. + * * @return Collection */ protected function _getProductCollection() @@ -141,6 +145,8 @@ protected function _getProductCollection() } /** + * Set search model. + * * @return Advanced */ public function getSearchModel() @@ -149,6 +155,8 @@ public function getSearchModel() } /** + * Get result count. + * * @return mixed */ public function getResultCount() @@ -161,6 +169,8 @@ public function getResultCount() } /** + * Get product list HTML. + * * @return string */ public function getProductListHtml() @@ -169,6 +179,8 @@ public function getProductListHtml() } /** + * Get form URL. + * * @return string */ public function getFormUrl() @@ -182,6 +194,8 @@ public function getFormUrl() } /** + * Get search criteria. + * * @return array */ public function getSearchCriterias() diff --git a/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php b/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php index bc60a5c9b106c..4942b36743c12 100644 --- a/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php +++ b/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php @@ -10,10 +10,13 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; +/** + * Advanced search controller. + */ class Index extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface, HttpPostActionInterface { /** - * @return \Magento\Framework\Controller\ResultInterface + * @inheritdoc */ public function execute() { diff --git a/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php b/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php index 145db146347bc..17d70e38d3b61 100644 --- a/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php +++ b/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php @@ -12,6 +12,9 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\UrlFactory; +/** + * Advanced search result. + */ class Result extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface, HttpPostActionInterface { /** @@ -46,7 +49,7 @@ public function __construct( } /** - * @return \Magento\Framework\Controller\Result\Redirect + * @inheritdoc */ public function execute() { diff --git a/app/code/Magento/CatalogSearch/Controller/Result/Index.php b/app/code/Magento/CatalogSearch/Controller/Result/Index.php index df00e4c7106ba..fba4572cf2c10 100644 --- a/app/code/Magento/CatalogSearch/Controller/Result/Index.php +++ b/app/code/Magento/CatalogSearch/Controller/Result/Index.php @@ -15,6 +15,9 @@ use Magento\Search\Model\QueryFactory; use Magento\Search\Model\PopularSearchTerms; +/** + * Search result. + */ class Index extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface, HttpPostActionInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php index 8f1f3fde14240..cea42347dc3f9 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Aggregation/Checker/Query/AdvancedSearch.php @@ -29,7 +29,7 @@ public function __construct($name) } /** - * {@inheritdoc} + * @inheritdoc */ public function isApplicable(RequestInterface $request) { diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Options.php b/app/code/Magento/CatalogSearch/Model/Adapter/Options.php index 425e6c0041616..f2e1c3c4c42d2 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Options.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Options.php @@ -10,6 +10,8 @@ use Magento\Store\Model\ScopeInterface; /** + * Catalog search config. + * * @api * @since 100.0.2 */ @@ -33,7 +35,7 @@ public function __construct(ScopeConfigInterface $scopeConfig) } /** - * {@inheritdoc} + * @inheritdoc */ public function get() { diff --git a/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php b/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php index 5447ff635f992..1f11d2650334d 100644 --- a/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php +++ b/app/code/Magento/CatalogSearch/Model/Adminhtml/System/Config/Backend/Engine.php @@ -6,6 +6,8 @@ namespace Magento\CatalogSearch\Model\Adminhtml\System\Config\Backend; /** + * Backend model for catalog search engine system config + * * @api * @since 100.0.2 */ @@ -42,6 +44,7 @@ public function __construct( /** * After save call + * * Invalidate catalog search index if engine was changed * * @return $this diff --git a/app/code/Magento/CatalogSearch/Model/Advanced.php b/app/code/Magento/CatalogSearch/Model/Advanced.php index 28f67a7829e7e..af0e9ff5528cf 100644 --- a/app/code/Magento/CatalogSearch/Model/Advanced.php +++ b/app/code/Magento/CatalogSearch/Model/Advanced.php @@ -22,6 +22,7 @@ /** * Catalog advanced search model + * * @method int getEntityTypeId() * @method \Magento\CatalogSearch\Model\Advanced setEntityTypeId(int $value) * @method int getAttributeSetId() @@ -296,6 +297,8 @@ public function prepareProductCollection($collection) } /** + * Add search criteria. + * * @param EntityAttribute $attribute * @param mixed $value * @return void diff --git a/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php b/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php index d6110f4b3b2c9..fa42cadb8a2fa 100644 --- a/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php +++ b/app/code/Magento/CatalogSearch/Model/Attribute/SearchWeight.php @@ -7,8 +7,9 @@ namespace Magento\CatalogSearch\Model\Attribute; /** - * This plugin is responsible for processing of search_weight property of a product attribute, - * which is used to boost matches by specific attributes. + * This plugin is responsible for processing of search_weight property of a product attribute. + * + * 'search_weight' is used to boost matches by specific attributes. * * This is part of search accuracy customization functionality. */ diff --git a/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php index c1c9997bc83ea..f014c6d133187 100644 --- a/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Autocomplete/DataProvider.php @@ -13,6 +13,9 @@ use Magento\Framework\App\Config\ScopeConfigInterface as ScopeConfig; use Magento\Store\Model\ScopeInterface; +/** + * Catalog search auto-complete data provider. + */ class DataProvider implements DataProviderInterface { /** @@ -44,6 +47,7 @@ class DataProvider implements DataProviderInterface /** * @param QueryFactory $queryFactory * @param ItemFactory $itemFactory + * @param ScopeConfig $scopeConfig */ public function __construct( QueryFactory $queryFactory, @@ -60,7 +64,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getItems() { 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 a8d46911193a8..03c3a50d1714b 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -12,6 +12,8 @@ use Magento\Store\Model\Store; /** + * Catalog search full test search data provider. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) * @api diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php index 83ad7acca84dc..86dccf8cfe559 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php @@ -7,6 +7,9 @@ use Magento\CatalogSearch\Model\Indexer\Fulltext; +/** + * Catalog search indexer plugin for catalog attribute. + */ class Attribute extends AbstractPlugin { /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php index ca701db7d2a93..1218e3da9a783 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Category.php @@ -9,6 +9,9 @@ use Magento\Catalog\Model\ResourceModel\Category as ResourceCategory; use Magento\Framework\Model\AbstractModel; +/** + * Catalog search indexer plugin for catalog category. + */ class Category extends AbstractPlugin { /** @@ -26,6 +29,8 @@ public function aroundSave(ResourceCategory $resourceCategory, \Closure $proceed } /** + * Reindex catalog search. + * * @param ResourceCategory $resourceCategory * @param \Closure $proceed * @param AbstractModel $category diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php index c8dbd89017b7c..e250d1123937a 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product.php @@ -9,9 +9,14 @@ use Magento\Catalog\Model\ResourceModel\Product as ResourceProduct; use Magento\Framework\Model\AbstractModel; +/** + * Catalog search indexer plugin for catalog product. + */ class Product extends AbstractPlugin { /** + * Reindex on product save. + * * @param ResourceProduct $productResource * @param \Closure $proceed * @param AbstractModel $product @@ -38,6 +43,8 @@ public function aroundDelete(ResourceProduct $productResource, \Closure $proceed } /** + * Reindex catalog search. + * * @param ResourceProduct $productResource * @param \Closure $proceed * @param AbstractModel $product diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php index e971f59cf10f2..23ab52012f2e5 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Store.php @@ -11,6 +11,9 @@ use Magento\Framework\Indexer\ConfigInterface; use Magento\Framework\Event\ObserverInterface; +/** + * Catalog search indexer plugin for store. + */ class Store implements ObserverInterface { /** @@ -44,6 +47,8 @@ public function __construct( } /** + * Reindex catalog search. + * * @param \Magento\Store\Model\Store $store * @return void */ @@ -59,6 +64,8 @@ private function clearIndex(\Magento\Store\Model\Store $store) } /** + * Reindex catalog search on store modification. + * * @param \Magento\Framework\Event\Observer $observer * @return void */ diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php index d8b3c19ddb918..d54d6c939cccc 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructureFactory.php @@ -10,6 +10,8 @@ use Magento\Framework\Search\EngineResolverInterface; /** + * Index structure factory + * * @api * @since 100.1.0 */ diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php index b9b44df6f404f..841ee8708f264 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php @@ -10,6 +10,8 @@ use Magento\Framework\Search\EngineResolverInterface; /** + * Indexer handler factory. + * * @api * @since 100.0.2 */ diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php b/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php index 47a8681a73c60..b6639f760457b 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Mview/Action.php @@ -9,6 +9,9 @@ use Magento\Framework\Mview\ActionInterface; use Magento\Framework\Indexer\IndexerInterfaceFactory; +/** + * Catalog search materialized view index action. + */ class Action implements ActionInterface { /** diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php b/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php index 4ce286bf15922..c24665f4808d2 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Category/ItemCollectionProvider.php @@ -9,6 +9,9 @@ use Magento\Catalog\Model\Layer\ItemCollectionProviderInterface; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +/** + * Catalog search category layer collection provider. + */ class ItemCollectionProvider implements ItemCollectionProviderInterface { /** @@ -25,8 +28,7 @@ public function __construct(CollectionFactory $collectionFactory) } /** - * @param \Magento\Catalog\Model\Category $category - * @return \Magento\Catalog\Model\ResourceModel\Product\Collection + * @inheritdoc */ public function getCollection(\Magento\Catalog\Model\Category $category) { diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php index 7c15514f211d2..0998cf7a9b3ac 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php @@ -24,14 +24,16 @@ class Category extends AbstractFilter private $dataProvider; /** + * Category constructor. + * * @param \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Catalog\Model\Layer $layer * @param \Magento\Catalog\Model\Layer\Filter\Item\DataBuilder $itemDataBuilder - * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory * @param \Magento\Framework\Escaper $escaper - * @param CategoryManagerFactory $categoryManager + * @param \Magento\Catalog\Model\Layer\Filter\DataProvider\CategoryFactory $categoryDataProviderFactory * @param array $data + * @throws \Magento\Framework\Exception\LocalizedException */ public function __construct( \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory, diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php index 108f1b9f4fd8d..a19f53469ae01 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php @@ -86,6 +86,8 @@ public function __construct( } /** + * Get resource model. + * * @return \Magento\Catalog\Model\ResourceModel\Layer\Filter\Price */ public function getResource() @@ -223,6 +225,8 @@ protected function _getItemsData() } /** + * Get 'to' part of the filter. + * * @param float $from * @return float */ @@ -237,6 +241,8 @@ protected function getTo($from) } /** + * Get 'from' part of the filter. + * * @param float $from * @return float */ @@ -251,6 +257,8 @@ protected function getFrom($from) } /** + * Prepare filter data. + * * @param string $key * @param int $count * @return array diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php b/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php index 4ffd8ff4ba5ea..eb901498c4ea5 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Search/Plugin/CollectionFilter.php @@ -9,6 +9,9 @@ use Magento\Catalog\Model\Category; use Magento\Search\Model\QueryFactory; +/** + * Catalog search plugin for search collection filter in layered navigation. + */ class CollectionFilter { /** diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php b/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php index 4f14b7daba1d5..98caccea2ae49 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Search/StateKey.php @@ -9,6 +9,9 @@ use Magento\Catalog\Model\Layer\StateKeyInterface; +/** + * Catalog search state key for layered navigation. + */ class StateKey extends \Magento\Catalog\Model\Layer\Category\StateKey implements StateKeyInterface { /** @@ -31,8 +34,7 @@ public function __construct( } /** - * @param \Magento\Catalog\Model\Category $category - * @return string|void + * @inheritdoc */ public function toString($category) { diff --git a/app/code/Magento/CatalogSearch/Model/Price/Interval.php b/app/code/Magento/CatalogSearch/Model/Price/Interval.php index db1d550c3724b..ea2d24aeadfd1 100644 --- a/app/code/Magento/CatalogSearch/Model/Price/Interval.php +++ b/app/code/Magento/CatalogSearch/Model/Price/Interval.php @@ -7,6 +7,9 @@ use Magento\Framework\Search\Dynamic\IntervalInterface; +/** + * Catalog search price interval. + */ class Interval implements IntervalInterface { /** @@ -23,7 +26,7 @@ public function __construct(\Magento\Catalog\Model\ResourceModel\Layer\Filter\Pr } /** - * {@inheritdoc} + * @inheritdoc */ public function load($limit, $offset = null, $lower = null, $upper = null) { @@ -32,7 +35,7 @@ public function load($limit, $offset = null, $lower = null, $upper = null) } /** - * {@inheritdoc} + * @inheritdoc */ public function loadPrevious($data, $index, $lower = null) { @@ -41,7 +44,7 @@ public function loadPrevious($data, $index, $lower = null) } /** - * {@inheritdoc} + * @inheritdoc */ public function loadNext($data, $rightIndex, $upper = null) { @@ -50,6 +53,8 @@ public function loadNext($data, $rightIndex, $upper = null) } /** + * Convert to float values. + * * @param array $prices * @return array */ diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php index 948ae70793c6f..b4b15554f6029 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php @@ -207,6 +207,8 @@ protected function _renderFiltersBefore() } /** + * Get attribute code. + * * @param string $attributeCode * @return string */ @@ -266,6 +268,8 @@ private function addRangeAttributeToSearch($attributeCode, $attributeValue) } /** + * Get search. + * * @return \Magento\Search\Api\SearchInterface */ private function getSearch() @@ -278,6 +282,8 @@ private function getSearch() } /** + * Get search criteria builder. + * * @return SearchCriteriaBuilder */ private function getSearchCriteriaBuilder() @@ -290,6 +296,8 @@ private function getSearchCriteriaBuilder() } /** + * Get fielter builder. + * * @return FilterBuilder */ private function getFilterBuilder() diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index 81121b9d21e12..e6cfe8ca112f7 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -201,6 +201,8 @@ public function __construct( } /** + * Get search. + * * @deprecated 100.1.0 * @return \Magento\Search\Api\SearchInterface */ @@ -213,6 +215,8 @@ private function getSearch() } /** + * Test search. + * * @deprecated 100.1.0 * @param \Magento\Search\Api\SearchInterface $object * @return void @@ -224,6 +228,8 @@ public function setSearch(\Magento\Search\Api\SearchInterface $object) } /** + * Set search criteria builder. + * * @deprecated 100.1.0 * @return \Magento\Framework\Api\Search\SearchCriteriaBuilder */ @@ -237,6 +243,8 @@ private function getSearchCriteriaBuilder() } /** + * Set search criteria builder. + * * @deprecated 100.1.0 * @param \Magento\Framework\Api\Search\SearchCriteriaBuilder $object * @return void @@ -248,6 +256,8 @@ public function setSearchCriteriaBuilder(\Magento\Framework\Api\Search\SearchCri } /** + * Get filter builder. + * * @deprecated 100.1.0 * @return \Magento\Framework\Api\FilterBuilder */ @@ -260,6 +270,8 @@ private function getFilterBuilder() } /** + * Set filter builder. + * * @deprecated 100.1.0 * @param \Magento\Framework\Api\FilterBuilder $object * @return void @@ -274,7 +286,7 @@ public function setFilterBuilder(\Magento\Framework\Api\FilterBuilder $object) * Apply attribute filter to facet collection * * @param string $field - * @param null $condition + * @param mixed|null $condition * @return $this */ public function addFieldToFilter($field, $condition = null) @@ -387,6 +399,8 @@ protected function _beforeLoad() } /** + * Render filters. + * * @return $this */ protected function _renderFilters() diff --git a/app/code/Magento/Search/Model/Query.php b/app/code/Magento/Search/Model/Query.php index b104fd0329795..d8c92a4801e8c 100644 --- a/app/code/Magento/Search/Model/Query.php +++ b/app/code/Magento/Search/Model/Query.php @@ -295,8 +295,7 @@ public function getMaxQueryLength() } /** - * @return string - * @codeCoverageIgnore + * @inheritdoc */ public function getQueryText() { @@ -304,6 +303,8 @@ public function getQueryText() } /** + * Check if query maximum length exceeded. + * * @return bool * @codeCoverageIgnore */ @@ -313,6 +314,8 @@ public function isQueryTextExceeded() } /** + * Check if minimum query length reached. + * * @return bool * @codeCoverageIgnore * @since 100.1.0 From e728763d084f12d34a06ccfedb1bc90b651658cd Mon Sep 17 00:00:00 2001 From: Daniel Ruf <daniel@daniel-ruf.de> Date: Wed, 17 Oct 2018 23:24:35 +0200 Subject: [PATCH 359/812] fix: cache count() results for loops --- app/code/Magento/Paypal/Model/Report/Settlement.php | 3 ++- .../Test/TestCase/Product/AddCompareProductsTest.php | 3 ++- .../Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php | 3 ++- .../Test/TestStep/FillShippingInformationStep.php | 3 ++- .../Test/Constraint/AssertProductsQtyAfterOrderCancel.php | 3 ++- .../Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php | 3 ++- .../Magento/Sniffs/Translation/ConstantUsageSniffTest.php | 3 ++- .../testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php | 5 +++-- .../Framework/App/Test/Unit/Language/DictionaryTest.php | 3 ++- lib/internal/Magento/Framework/Archive.php | 7 ++++--- lib/internal/Magento/Framework/Cache/Backend/Memcached.php | 3 ++- lib/internal/Magento/Framework/Filter/Template.php | 3 ++- lib/internal/Magento/Framework/System/Ftp.php | 3 ++- .../src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php | 6 ++++-- setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php | 6 ++++-- 15 files changed, 37 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Paypal/Model/Report/Settlement.php b/app/code/Magento/Paypal/Model/Report/Settlement.php index 5dc51518f0b11..b2ab1627b24d4 100644 --- a/app/code/Magento/Paypal/Model/Report/Settlement.php +++ b/app/code/Magento/Paypal/Model/Report/Settlement.php @@ -409,7 +409,8 @@ public function parseCsv($localCsv, $format = 'new') private function getBodyItems(array $line, array $sectionColumns, array $rowMap) { $bodyItem = []; - for ($i = 1, $count = count($line); $i < $count; $i++) { + $lineCount = count($line); + for ($i = 1, $count = $lineCount; $i < $count; $i++) { if (isset($rowMap[$sectionColumns[$i]])) { if (in_array($rowMap[$sectionColumns[$i]], $this->dateTimeColumns)) { $line[$i] = $this->formatDateTimeColumns($line[$i]); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php index c700dbc362cbb..da0aa49d9697b 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php @@ -76,7 +76,8 @@ public function tearDown() { $this->cmsIndex->open(); $this->cmsIndex->getLinksBlock()->openLink("Compare Products"); - for ($i = 1; $i <= count($this->products); $i++) { + $productsCount = count($this->products); + for ($i = 1; $i <= $productsCount; $i++) { $this->catalogProductCompare->getCompareProductsBlock()->removeProduct(); } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php index bdd54ce3559f9..381c18d3ee686 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php @@ -95,7 +95,8 @@ public function test( $customers = []; $cartFixtures = []; - for ($i = 0; $i < count($checkoutData); $i++) { + $checkoutDataCount = count($checkoutData); + for ($i = 0; $i < $checkoutDataCount; $i++) { $customers[$i] = $this->fixtureFactory->createByCode('customer', ['dataset' => $customerDataset]); $customers[$i]->persist(); diff --git a/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php b/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php index 67c1826f40a24..248dfc8e16dc9 100644 --- a/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php +++ b/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php @@ -58,7 +58,8 @@ public function __construct( public function run() { $shippingMethods = []; - for ($i = 0; $i < count($this->customer->getAddress()); $i++) { + $addressCount = $this->customer->getAddress(); + for ($i = 0; $i < $addressCount; $i++) { $shippingMethods[] = $this->shippingMethod; } $this->shippingInformation->getShippingBlock()->selectShippingMethod($shippingMethods); diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php index 28259c8f6d93b..7d229bc358995 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php @@ -52,7 +52,8 @@ public function processAssert( AssertProductForm $assertProductForm, AssertConfigurableProductForm $assertConfigurableProductForm ) { - for ($i = 0; $i < count($order->getEntityId()['products']); $i++) { + $productsCount = count($order->getEntityId()['products']); + for ($i = 0; $i < $productsCount; $i++) { $product = $order->getEntityId()['products'][$i]; $productData = $product->getData(); if ($product instanceof BundleProduct) { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php index 4b69bcd4615db..87ba4d7c2808c 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php @@ -112,7 +112,8 @@ public function testPricesSegmentation($categoryId, array $entityIds, array $int $items = $model->calculateSeparators($interval); $this->assertEquals(array_keys($intervalItems), array_keys($items)); - for ($i = 0; $i < count($intervalItems); ++$i) { + $intervalItemsCount = count($intervalItems); + for ($i = 0; $i < $intervalItemsCount; ++$i) { $this->assertInternalType('array', $items[$i]); $this->assertEquals($intervalItems[$i]['from'], $items[$i]['from']); $this->assertEquals($intervalItems[$i]['to'], $items[$i]['to']); diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php index 39ad80850dd30..06a8a0accc732 100644 --- a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php @@ -67,7 +67,8 @@ private function tokenizeString($fileContent) $lineNumber = 1; $tokens = token_get_all($fileContent); $snifferTokens = []; - for ($i = 0; $i < count($tokens); $i++) { + $tokensCount = count($tokens); + for ($i = 0; $i < $tokensCount; $i++) { $content = is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i]; $snifferTokens[$i]['line'] = $lineNumber; $snifferTokens[$i]['content'] = $content; diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php index 2a6079d619d4c..0560158a82668 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php @@ -501,8 +501,9 @@ private function _checkConstantWithClasspath($constant, $class, $replacement, $c { $classPathParts = explode('\\', $class); $classPartialPath = ''; - for ($i = count($classPathParts) - 1; $i >= 0; $i--) { - if ($i === (count($classPathParts) - 1)) { + $classPathPartsCount = count($classPathParts); + for ($i = $classPathPartsCount - 1; $i >= 0; $i--) { + if ($i === ($classPathPartsCount - 1)) { $classPartialPath = $classPathParts[$i] . $classPartialPath; } else { $classPartialPath = $classPathParts[$i] . '\\' . $classPartialPath; diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php index 472fff4f4f287..67518a6c7d142 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php @@ -52,7 +52,8 @@ public function testDictionaryGetter() } $file = $this->getMockForAbstractClass(\Magento\Framework\Filesystem\File\ReadInterface::class); - for ($i = 0; $i < count($data); $i++) { + $dataCount = count($data); + for ($i = 0; $i < $dataCount; $i++) { $file->expects($this->at($i))->method('readCsv')->will($this->returnValue($data[$i])); } $file->expects($this->at($i))->method('readCsv')->will($this->returnValue(false)); diff --git a/lib/internal/Magento/Framework/Archive.php b/lib/internal/Magento/Framework/Archive.php index d43c976431b51..7c4b6984b3fc4 100644 --- a/lib/internal/Magento/Framework/Archive.php +++ b/lib/internal/Magento/Framework/Archive.php @@ -96,14 +96,15 @@ public function pack($source, $destination = 'packed.tgz', $skipRoot = false) { $archivers = $this->_getArchivers($destination); $interimSource = ''; - for ($i = 0; $i < count($archivers); $i++) { - if ($i == count($archivers) - 1) { + $archiversCount = count($archivers); + for ($i = 0; $i < $archiversCount; $i++) { + if ($i == $archiversCount - 1) { $packed = $destination; } else { $packed = dirname($destination) . '/~tmp-' . microtime(true) . $archivers[$i] . '.' . $archivers[$i]; } $source = $this->_getArchiver($archivers[$i])->pack($source, $packed, $skipRoot); - if ($interimSource && $i < count($archivers)) { + if ($interimSource && $i < $archiversCount) { unlink($interimSource); } $interimSource = $source; diff --git a/lib/internal/Magento/Framework/Cache/Backend/Memcached.php b/lib/internal/Magento/Framework/Cache/Backend/Memcached.php index c5e7a7e9e7c09..c793714f69153 100644 --- a/lib/internal/Magento/Framework/Cache/Backend/Memcached.php +++ b/lib/internal/Magento/Framework/Cache/Backend/Memcached.php @@ -84,7 +84,8 @@ public function save($data, $id, $tags = [], $specificLifetime = false) if (is_string($data) && strlen($data) > $this->_options['slab_size']) { $dataChunks = str_split($data, $this->_options['slab_size']); - for ($i = 0, $cnt = count($dataChunks); $i < $cnt; $i++) { + $dataChunksCount = count($dataChunks); + for ($i = 0, $cnt = $dataChunksCount; $i < $cnt; $i++) { $chunkId = $this->_getChunkId($id, $i); if (!parent::save($dataChunks[$i], $chunkId, $tags, $specificLifetime)) { diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 10b6a17ea57dc..27797d0867924 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -374,7 +374,8 @@ protected function getVariable($value, $default = '{no_value_defined}') $stackVars = $tokenizer->tokenize(); $result = $default; $last = 0; - for ($i = 0; $i < count($stackVars); $i++) { + $stackVarsCount = count($stackVars); + for ($i = 0; $i < $stackVarsCount; $i++) { if ($i == 0 && isset($this->templateVars[$stackVars[$i]['name']])) { // Getting of template value $stackVars[$i]['variable'] = & $this->templateVars[$stackVars[$i]['name']]; diff --git a/lib/internal/Magento/Framework/System/Ftp.php b/lib/internal/Magento/Framework/System/Ftp.php index ad0673ff5d7d3..c915d50741dd2 100644 --- a/lib/internal/Magento/Framework/System/Ftp.php +++ b/lib/internal/Magento/Framework/System/Ftp.php @@ -56,7 +56,8 @@ public function mkdirRecursive($path, $mode = 0777) $dir = explode("/", $path); $path = ""; $ret = true; - for ($i = 0; $i < count($dir); $i++) { + $dirCount = count($dir); + for ($i = 0; $i < $dirCount; $i++) { $path .= "/" . $dir[$i]; if (!@ftp_chdir($this->_conn, $path)) { @ftp_chdir($this->_conn, "/"); diff --git a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php index a4e3063abece4..9112192f6eb27 100644 --- a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php +++ b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php @@ -31,7 +31,8 @@ protected function _parse() $results = []; preg_match_all(Filter::CONSTRUCTION_PATTERN, $data, $results, PREG_SET_ORDER); - for ($i = 0; $i < count($results); $i++) { + $resultsCount = count($results); + for ($i = 0; $i < $resultsCount; $i++) { if ($results[$i][1] === Filter::TRANS_DIRECTIVE_NAME) { $directive = []; if (preg_match(Filter::TRANS_DIRECTIVE_REGEX, $results[$i][2], $directive) !== 1) { @@ -43,7 +44,8 @@ protected function _parse() } preg_match_all(self::HTML_FILTER, $data, $results, PREG_SET_ORDER); - for ($i = 0; $i < count($results); $i++) { + $resultsCount = count($results); + for ($i = 0; $i < $resultsCount; $i++) { if (!empty($results[$i]['value'])) { $this->_addPhrase($results[$i]['value']); } diff --git a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php index 4095b12c9a6c6..0f6a402e2609c 100644 --- a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php +++ b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php @@ -22,7 +22,8 @@ protected function _parse() $fileRow = fgets($fileHandle, 4096); $results = []; preg_match_all('/mage\.__\(\s*([\'"])(.*?[^\\\])\1.*?[),]/', $fileRow, $results, PREG_SET_ORDER); - for ($i = 0; $i < count($results); $i++) { + $resultsCount = count($results); + for ($i = 0; $i < $resultsCount; $i++) { if (isset($results[$i][2])) { $quote = $results[$i][1]; $this->_addPhrase($quote . $results[$i][2] . $quote, $lineNumber); @@ -30,7 +31,8 @@ protected function _parse() } preg_match_all('/\\$t\(\s*([\'"])(.*?[^\\\])\1.*?[),]/', $fileRow, $results, PREG_SET_ORDER); - for ($i = 0; $i < count($results); $i++) { + $resultsCount = count($results); + for ($i = 0; $i < $resultsCount; $i++) { if (isset($results[$i][2])) { $quote = $results[$i][1]; $this->_addPhrase($quote . $results[$i][2] . $quote, $lineNumber); From 7194fc81543fa40633ad0bfdb1ca23502a3330b7 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 17 Oct 2018 17:02:17 -0500 Subject: [PATCH 360/812] MAGETWO-71686: File is imported error - Fixed error aggregator not obeying the validation strategy from the UI --- .../ImportExport/Controller/Adminhtml/Import/Start.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index 8896f84ce2471..eb691d011a292 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -8,6 +8,7 @@ use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\ImportExport\Controller\Adminhtml\ImportResult as ImportResultController; use Magento\Framework\Controller\ResultFactory; +use Magento\ImportExport\Model\Import; class Start extends ImportResultController implements HttpPostActionInterface { @@ -63,6 +64,11 @@ public function execute() $this->importModel->setData($data); $errorAggregator = $this->importModel->getErrorAggregator(); + $errorAggregator->initValidationStrategy( + $this->importModel->getData(Import::FIELD_NAME_VALIDATION_STRATEGY), + $this->importModel->getData(Import::FIELD_NAME_ALLOWED_ERROR_COUNT) + ); + try { $this->importModel->importSource(); } catch (\Exception $e) { From b65b49f1bae762988574a9d23f3892f3f65cc913 Mon Sep 17 00:00:00 2001 From: Ravi Chandra <ravi.chandra@krishtechnolabs.com> Date: Thu, 18 Oct 2018 12:12:23 +0530 Subject: [PATCH 361/812] Fix SKU limit in import new products for 2.3 with backward compatible allow 64 characters for SKU --- .../Model/Import/Product/Validator.php | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php index b184334b179ea..793ad935363d3 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php @@ -71,7 +71,7 @@ protected function textValidation($attrCode, $type) if ($type == 'text') { $valid = $this->string->strlen($val) < Product::DB_MAX_TEXT_LENGTH; } else if ($attrCode == Product::COL_SKU) { - $valid = $this->string->strlen($val) < SKU::SKU_MAX_LENGTH; + $valid = $this->string->strlen($val) <= SKU::SKU_MAX_LENGTH; } else { $valid = $this->string->strlen($val) < Product::DB_MAX_VARCHAR_LENGTH; } @@ -153,12 +153,7 @@ public function isRequiredAttributeValid($attrCode, array $attributeParams, arra $doCheck = true; } - if ($doCheck === true) { - return isset($rowData[$attrCode]) - && strlen(trim($rowData[$attrCode])) - && trim($rowData[$attrCode]) !== $this->context->getEmptyAttributeValueConstant(); - } - return true; + return $doCheck ? isset($rowData[$attrCode]) && strlen(trim($rowData[$attrCode])) : true; } /** @@ -196,11 +191,6 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData) if (!strlen(trim($rowData[$attrCode]))) { return true; } - - if ($rowData[$attrCode] === $this->context->getEmptyAttributeValueConstant() && !$attrParams['is_required']) { - return true; - } - switch ($attrParams['type']) { case 'varchar': case 'text': @@ -222,12 +212,6 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData) break; } } - - $uniqueValues = array_unique($values); - if (count($uniqueValues) != count($values)) { - $valid = false; - $this->_addMessages([RowValidatorInterface::ERROR_DUPLICATE_MULTISELECT_VALUES]); - } break; case 'datetime': $val = trim($rowData[$attrCode]); From 57902258f066e4802f026f64e12f48663475b0b3 Mon Sep 17 00:00:00 2001 From: Ravi Chandra <ravi.chandra@krishtechnolabs.com> Date: Thu, 18 Oct 2018 12:31:58 +0530 Subject: [PATCH 362/812] Fix SKU limit in import new products for 2.3 with backward compatible allow 64 characters --- .../Model/Import/Product/Validator.php | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php index 793ad935363d3..21f7f87875e12 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php @@ -153,7 +153,12 @@ public function isRequiredAttributeValid($attrCode, array $attributeParams, arra $doCheck = true; } - return $doCheck ? isset($rowData[$attrCode]) && strlen(trim($rowData[$attrCode])) : true; + if ($doCheck === true) { + return isset($rowData[$attrCode]) + && strlen(trim($rowData[$attrCode])) + && trim($rowData[$attrCode]) !== $this->context->getEmptyAttributeValueConstant(); + } + return true; } /** @@ -191,6 +196,11 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData) if (!strlen(trim($rowData[$attrCode]))) { return true; } + + if ($rowData[$attrCode] === $this->context->getEmptyAttributeValueConstant() && !$attrParams['is_required']) { + return true; + } + switch ($attrParams['type']) { case 'varchar': case 'text': @@ -212,6 +222,12 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData) break; } } + + $uniqueValues = array_unique($values); + if (count($uniqueValues) != count($values)) { + $valid = false; + $this->_addMessages([RowValidatorInterface::ERROR_DUPLICATE_MULTISELECT_VALUES]); + } break; case 'datetime': $val = trim($rowData[$attrCode]); @@ -328,4 +344,4 @@ public function init($context) $validator->init($context); } } -} +} \ No newline at end of file From cb2aadc99d86279fcb0f352b6972eedb26ba98de Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Thu, 18 Oct 2018 13:25:42 +0300 Subject: [PATCH 363/812] MAGETWO-95654: Constraint removal is not treated as destructive operation - Marked 'drop_reference' as destructive operation --- .../Declaration/Schema/Operations/DropReference.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/DropReference.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/DropReference.php index 4a5f651a10815..95fc1c42210be 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/DropReference.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/DropReference.php @@ -35,18 +35,15 @@ public function __construct(DropElement $dropElement) } /** - * {@inheritdoc} - * We can drop references and this will not cause any issues. - * - * @return bool + * @inheritdoc */ public function isOperationDestructive() { - return false; + return true; } /** - * {@inheritdoc} + * @inheritdoc */ public function getOperationName() { @@ -54,7 +51,7 @@ public function getOperationName() } /** - * {@inheritdoc} + * @inheritdoc */ public function doOperation(ElementHistory $elementHistory) { From 2fc6596cb403a788a0226b1ae03bea00b68bf26d Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <mikalai_shostka@epam.com> Date: Thu, 18 Oct 2018 15:57:24 +0300 Subject: [PATCH 364/812] MAGETWO-95445: Category Flat Data indexer doesnt show status as reindex required after deleting store/storeview - Delete abandoned tables in full reindex --- .../Catalog/Helper/Product/Flat/Indexer.php | 32 ---------- .../Indexer/Category/Flat/Action/Full.php | 63 +++++++++++-------- 2 files changed, 38 insertions(+), 57 deletions(-) diff --git a/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php b/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php index 0366e01ee86ea..93eaa23b89f16 100644 --- a/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php +++ b/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php @@ -466,17 +466,6 @@ public function getFlatTableName($storeId) return sprintf('%s_%s', $this->getTable('catalog_product_flat'), $storeId); } - /** - * Retrieve Catalog Product Flat Table name - * - * @param int $storeId - * @return string - */ - private function getCategoryFlatTableName(int $storeId): string - { - return sprintf('%s_store_%s', $this->getTable('catalog_category_flat'), $storeId); - } - /** * Retrieve loaded attribute by code * @@ -526,25 +515,4 @@ public function deleteAbandonedStoreFlatTables() $connection->dropTable($table); } } - - /** - * Delete all category flat tables for not existing stores - * - * @return void - */ - public function deleteAbandonedStoreCategoryFlatTables() - { - $connection = $this->_resource->getConnection(); - $existentTables = $connection->getTables($connection->getTableName('catalog_category_flat_store_%')); - $actualStoreTables = []; - foreach ($this->_storeManager->getStores() as $store) { - $actualStoreTables[] = $this->getCategoryFlatTableName($store->getId()); - } - - $tablesToDelete = array_diff($existentTables, $actualStoreTables); - - foreach ($tablesToDelete as $table) { - $connection->dropTable($table); - } - } } diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php index c1e6decf6afef..624001b498449 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php @@ -5,8 +5,6 @@ */ namespace Magento\Catalog\Model\Indexer\Category\Flat\Action; -use Magento\Framework\App\ResourceConnection; - /** * Class for full reindex flat categories */ @@ -24,28 +22,6 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction */ protected $allowTableChanges = true; - /** - * @var \Magento\Catalog\Helper\Product\Flat\Indexer - */ - private $indexer; - - /** - * @param ResourceConnection $resource - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper - * @param \Magento\Catalog\Helper\Product\Flat\Indexer $indexer - */ - public function __construct( - ResourceConnection $resource, - \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, - \Magento\Catalog\Helper\Product\Flat\Indexer $indexer = null - ) { - $this->indexer = $indexer ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Catalog\Helper\Product\Flat\Indexer::class); - parent::__construct($resource, $storeManager, $resourceHelper); - } - /** * Add suffix to table name to show it is old * @@ -196,6 +172,43 @@ protected function switchTables(array $stores = []) return $this; } + /** + * Retrieve all actual Catalog Product Flat Table names + * + * @return string[] + */ + private function getActualStoreTablesForCategoryFlat(): array + { + $actualStoreTables = []; + foreach ($this->storeManager->getStores() as $store) { + $actualStoreTables[] = sprintf( + '%s_store_%s', + $this->connection->getTableName('catalog_category_flat'), $store->getId() + ); + } + + return $actualStoreTables; + } + + /** + * Delete all category flat tables for not existing stores + * + * @return void + */ + private function deleteAbandonedStoreCategoryFlatTables(): void + { + $existentTables = $this->connection->getTables( + $this->connection->getTableName('catalog_category_flat_store_%') + ); + $actualStoreTables = $this->getActualStoreTablesForCategoryFlat(); + + $tablesToDelete = array_diff($existentTables, $actualStoreTables); + + foreach ($tablesToDelete as $table) { + $this->connection->dropTable($table); + } + } + /** * Transactional rebuild flat data from eav * @@ -211,7 +224,7 @@ public function reindexAll() $stores = $this->storeManager->getStores(); $this->populateFlatTables($stores); $this->switchTables($stores); - $this->indexer->deleteAbandonedStoreCategoryFlatTables(); + $this->deleteAbandonedStoreCategoryFlatTables(); $this->allowTableChanges = true; return $this; From bb4f60197ea9af573434f838ed61c014e3fbd132 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 18 Oct 2018 17:09:34 +0300 Subject: [PATCH 365/812] GraphQL-174: Absolute image paths for Products --- .../Model/Resolver/Product/Image.php | 66 ------------------- .../Model/Resolver/Product/ProductImage.php | 57 +++++++--------- 2 files changed, 22 insertions(+), 101 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php deleted file mode 100644 index 6830aecb78f10..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Product; - -use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\ImageFactory; -use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; - -/** - * Returns product's image. If the image is not set, returns a placeholder - */ -class Image implements ResolverInterface -{ - /** - * Product image factory - * - * @var ImageFactory - */ - private $productImageFactory; - - /** - * @param ImageFactory $productImageFactory - */ - public function __construct( - ImageFactory $productImageFactory - ) { - $this->productImageFactory = $productImageFactory; - } - - /** - * @inheritdoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ): array { - if (!isset($value['model'])) { - throw new LocalizedException(__('"model" value should be specified')); - } - /** @var Product $product */ - $product = $value['model']; - $imageType = $field->getName(); - $path = $product->getData($imageType); - - $image = $this->productImageFactory->create(); - $image->setDestinationSubdir($imageType) - ->setBaseFile($path); - $imageUrl = $image->getUrl(); - - return [ - 'url' => $imageUrl, - 'path' => $path, - ]; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php index 9dc0dd68ee457..3caa79e68c235 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php @@ -8,43 +8,34 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Catalog\Model\Product; -use Magento\Catalog\Helper\ImageFactory as CatalogImageHelperFactory; +use Magento\Catalog\Model\Product\ImageFactory; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Store\Model\StoreManagerInterface; /** - * Return product image paths by image type. + * Returns product's image data */ class ProductImage implements ResolverInterface { /** - * @var CatalogImageHelperFactory - */ - private $catalogImageHelperFactory; - - /** - * @var StoreManagerInterface + * Product image factory + * + * @var ImageFactory */ - private $storeManager; + private $productImageFactory; /** - * @param CatalogImageHelperFactory $catalogImageHelperFactory - * @param StoreManagerInterface $storeManager + * @param ImageFactory $productImageFactory */ public function __construct( - CatalogImageHelperFactory $catalogImageHelperFactory, - StoreManagerInterface $storeManager + ImageFactory $productImageFactory ) { - $this->catalogImageHelperFactory = $catalogImageHelperFactory; - $this->storeManager = $storeManager; + $this->productImageFactory = $productImageFactory; } /** - * Get product's image by type. - * * @inheritdoc */ public function resolve( @@ -53,30 +44,26 @@ public function resolve( ResolveInfo $info, array $value = null, array $args = null - ) { + ): array { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ $product = $value['model']; $imageType = $field->getName(); - /** @var \Magento\Catalog\Helper\Image $catalogImageHelper */ - $catalogImageHelper = $this->catalogImageHelperFactory->create(); + $imagePath = $product->getData($imageType); + $imageLabel = $product->getData($imageType . '_' . 'label') ?? $product->getName(); - /** @var \Magento\Catalog\Helper\Image $image */ - $image = $catalogImageHelper->init( - $product, - 'product_' . $imageType, - ['type' => $imageType] - ); + $image = $this->productImageFactory->create(); + $image->setDestinationSubdir($imageType) + ->setBaseFile($imagePath); + $imageUrl = $image->getUrl(); - $imageData = [ - 'url' => $image->getUrl(), - 'path' => $product->getData($imageType), - 'label' => $image->getLabel() + return [ + 'url' => $imageUrl, + 'path' => $imagePath, + 'label' => $imageLabel, ]; - - return $imageData; } } From dc76327173dca206638feff496363757c6509693 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 18 Oct 2018 09:15:47 -0500 Subject: [PATCH 366/812] MAGETWO-71686: File is imported error - Fixed static issue --- .../Magento/ImportExport/Controller/Adminhtml/Import/Start.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index eb691d011a292..8f64d023c19f9 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -10,6 +10,9 @@ use Magento\Framework\Controller\ResultFactory; use Magento\ImportExport\Model\Import; +/** + * Controller responsible for initiating the import process + */ class Start extends ImportResultController implements HttpPostActionInterface { /** From c02a00a171d4a9aaae6afc43205717718d026038 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 18 Oct 2018 10:55:03 -0500 Subject: [PATCH 367/812] MAGETWO-95471: [Forwardport] Layered navigation price step issue with Elasticsearch 2+ - Applied existing fix - Added test coverage --- .../Elasticsearch/SearchAdapter/Dynamic/DataProvider.php | 2 +- .../Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php b/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php index 0add517ba94ad..527260699e161 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php @@ -209,7 +209,7 @@ public function getAggregation( 'prices' => [ 'histogram' => [ 'field' => $fieldName, - 'interval' => $range, + 'interval' => (float)$range, ], ], ]; diff --git a/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php b/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php index 41be237efe532..a7914ceec12d7 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php @@ -320,6 +320,10 @@ public function testGetAggregation() $this->clientMock->expects($this->once()) ->method('query') + ->with($this->callback(function($query) { + // Assert the interval is queried as a float. See MAGETWO-95471 + return $query['body']['aggregations']['prices']['histogram']['interval'] === 10.0; + })) ->willReturn([ 'aggregations' => [ 'prices' => [ From daa937c48c06a476baa8a02d896d94e414334cfd Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 18 Oct 2018 11:00:35 -0500 Subject: [PATCH 368/812] MAGETWO-95471: [Forwardport] Layered navigation price step issue with Elasticsearch 2+ - Static fixes --- .../SearchAdapter/Dynamic/DataProvider.php | 12 +++++++----- .../Unit/SearchAdapter/Dynamic/DataProviderTest.php | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php b/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php index 527260699e161..e99da34533475 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Dynamic/DataProvider.php @@ -9,6 +9,8 @@ use Magento\Elasticsearch\SearchAdapter\QueryContainer; /** + * Provides data for search using ElasticSearch + * * @api * @since 100.1.0 */ @@ -120,7 +122,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function getRange() @@ -129,7 +131,7 @@ public function getRange() } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function getAggregations(\Magento\Framework\Search\Dynamic\EntityStorage $entityStorage) @@ -168,7 +170,7 @@ public function getAggregations(\Magento\Framework\Search\Dynamic\EntityStorage } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function getInterval( @@ -191,7 +193,7 @@ public function getInterval( } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function getAggregation( @@ -225,7 +227,7 @@ public function getAggregation( } /** - * {@inheritdoc} + * @inheritdoc * @since 100.1.0 */ public function prepareData($range, array $dbRanges) diff --git a/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php b/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php index a7914ceec12d7..9c717ea240a5d 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Dynamic/DataProviderTest.php @@ -320,7 +320,7 @@ public function testGetAggregation() $this->clientMock->expects($this->once()) ->method('query') - ->with($this->callback(function($query) { + ->with($this->callback(function ($query) { // Assert the interval is queried as a float. See MAGETWO-95471 return $query['body']['aggregations']['prices']['histogram']['interval'] === 10.0; })) From 7a326128f10815e5ef05c94bef26ba1ab4f9087b Mon Sep 17 00:00:00 2001 From: Igor Miniailo <igor.minyaylo@gmail.com> Date: Thu, 18 Oct 2018 19:38:32 +0300 Subject: [PATCH 369/812] MSI-1735: Add @deprecated PHP DocBlock to all public interfaces and extension points of module CatalogInventory --- .../CatalogInventory/Api/Data/StockCollectionInterface.php | 5 +++-- .../Magento/CatalogInventory/Api/Data/StockInterface.php | 5 +++-- .../Api/Data/StockItemCollectionInterface.php | 5 +++-- .../Magento/CatalogInventory/Api/Data/StockItemInterface.php | 5 +++-- .../Api/Data/StockStatusCollectionInterface.php | 5 +++-- .../CatalogInventory/Api/Data/StockStatusInterface.php | 5 +++-- .../CatalogInventory/Api/RegisterProductSaleInterface.php | 5 +++-- .../CatalogInventory/Api/RevertProductSaleInterface.php | 5 +++-- .../CatalogInventory/Api/StockConfigurationInterface.php | 5 +++-- .../Magento/CatalogInventory/Api/StockCriteriaInterface.php | 5 +++-- .../Magento/CatalogInventory/Api/StockIndexInterface.php | 5 +++-- .../CatalogInventory/Api/StockItemCriteriaInterface.php | 5 +++-- .../CatalogInventory/Api/StockItemRepositoryInterface.php | 5 +++-- .../CatalogInventory/Api/StockManagementInterface.php | 5 +++-- .../Magento/CatalogInventory/Api/StockRegistryInterface.php | 5 +++-- .../CatalogInventory/Api/StockRepositoryInterface.php | 5 +++-- .../Magento/CatalogInventory/Api/StockStateInterface.php | 5 +++-- .../CatalogInventory/Api/StockStatusCriteriaInterface.php | 5 +++-- .../CatalogInventory/Api/StockStatusRepositoryInterface.php | 5 +++-- .../Block/Adminhtml/Form/Field/Minsaleqty.php | 5 +++-- .../CatalogInventory/Block/Adminhtml/Form/Field/Stock.php | 5 +++-- app/code/Magento/CatalogInventory/Block/Qtyincrements.php | 5 +++-- .../CatalogInventory/Block/Stockqty/DefaultStockqty.php | 5 +++-- app/code/Magento/CatalogInventory/Helper/Stock.php | 5 +++-- .../Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php | 5 +++-- .../CatalogInventory/Model/Quote/Item/QuantityValidator.php | 5 +++-- .../Model/ResourceModel/Indexer/Stock/DefaultStock.php | 5 +++-- .../ResourceModel/Indexer/Stock/QueryProcessorInterface.php | 5 +++-- .../Model/ResourceModel/Indexer/Stock/StockInterface.php | 5 +++-- .../Model/ResourceModel/Indexer/StockFactory.php | 5 +++-- .../CatalogInventory/Model/ResourceModel/Stock/Status.php | 5 +++-- .../Magento/CatalogInventory/Model/Source/Backorders.php | 5 +++-- app/code/Magento/CatalogInventory/Model/Source/Stock.php | 5 +++-- 33 files changed, 99 insertions(+), 66 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php index a0f06cd406b14..9ae22e5e1a364 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockCollectionInterface.php @@ -16,8 +16,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockCollectionInterface extends SearchResultsInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php index 2bc9b474ff298..087fae6e6568a 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php @@ -12,8 +12,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockInterface extends ExtensibleDataInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php index dbb8602678d80..59a1f58b74c2c 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockItemCollectionInterface.php @@ -16,8 +16,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockItemCollectionInterface extends SearchResultsInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php index 2daebf96c6c02..e2e8a744c4bcd 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php @@ -12,8 +12,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockItemInterface extends ExtensibleDataInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php index 35959017606ad..1cc045745a0c1 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockStatusCollectionInterface.php @@ -12,8 +12,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockStatusCollectionInterface extends SearchResultsInterface { diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php index 397048cb04628..66b639fb088d1 100644 --- a/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php +++ b/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php @@ -12,8 +12,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockStatusInterface extends ExtensibleDataInterface { diff --git a/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php b/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php index 2f2b97bf1fa93..6fd1e7466970d 100644 --- a/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php +++ b/app/code/Magento/CatalogInventory/Api/RegisterProductSaleInterface.php @@ -13,8 +13,9 @@ /** * @api * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface RegisterProductSaleInterface { diff --git a/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php b/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php index 0f441ee6268a1..552e30da89235 100644 --- a/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php +++ b/app/code/Magento/CatalogInventory/Api/RevertProductSaleInterface.php @@ -10,8 +10,9 @@ /** * @api * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface RevertProductSaleInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php b/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php index be815c3145607..5019e86b7af40 100644 --- a/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockConfigurationInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockConfigurationInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php b/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php index d92d2931867bc..eb6fb2e812f2e 100644 --- a/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockCriteriaInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php b/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php index 5a4c4b7ef52a1..18bab6571c209 100644 --- a/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockIndexInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockIndexInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php b/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php index 5d129c199fc8a..1d2cabbb48a11 100644 --- a/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockItemCriteriaInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockItemCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php b/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php index 90f7d993e3607..eecf6cbe07632 100644 --- a/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockItemRepositoryInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockItemRepositoryInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php b/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php index dcd611a148398..8796953e32fd0 100644 --- a/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockManagementInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockManagementInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php b/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php index 7e3ee63d33aee..5478f90fb7d9f 100644 --- a/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockRegistryInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockRegistryInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php b/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php index 2b0c40582932d..3cfdf45506340 100644 --- a/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockRepositoryInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockRepositoryInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockStateInterface.php b/app/code/Magento/CatalogInventory/Api/StockStateInterface.php index 49cc746e79d39..8be7f5be79f27 100644 --- a/app/code/Magento/CatalogInventory/Api/StockStateInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockStateInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockStateInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php b/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php index f57db6b2cef0a..99ad7005d9da4 100644 --- a/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockStatusCriteriaInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockStatusCriteriaInterface extends \Magento\Framework\Api\CriteriaInterface { diff --git a/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php b/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php index 8be61afbbce11..d29171f557f05 100644 --- a/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php +++ b/app/code/Magento/CatalogInventory/Api/StockStatusRepositoryInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockStatusRepositoryInterface { diff --git a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php index 38d3c33a9a1f8..d3c165bbde1a8 100644 --- a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php +++ b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Minsaleqty.php @@ -11,8 +11,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Minsaleqty extends \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray { diff --git a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php index 74e062b7e07ca..5378801b6c24b 100644 --- a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php +++ b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php @@ -15,8 +15,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Stock extends \Magento\Framework\Data\Form\Element\Select { diff --git a/app/code/Magento/CatalogInventory/Block/Qtyincrements.php b/app/code/Magento/CatalogInventory/Block/Qtyincrements.php index 9551e06264c1b..a12b72cd0a971 100644 --- a/app/code/Magento/CatalogInventory/Block/Qtyincrements.php +++ b/app/code/Magento/CatalogInventory/Block/Qtyincrements.php @@ -15,8 +15,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Qtyincrements extends Template implements IdentityInterface { diff --git a/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php b/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php index cb8741c88b09d..5a3a3ca6ee983 100644 --- a/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php +++ b/app/code/Magento/CatalogInventory/Block/Stockqty/DefaultStockqty.php @@ -12,8 +12,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class DefaultStockqty extends AbstractStockqty implements \Magento\Framework\DataObject\IdentityInterface { diff --git a/app/code/Magento/CatalogInventory/Helper/Stock.php b/app/code/Magento/CatalogInventory/Helper/Stock.php index eb76dd5fce057..798ac4074c188 100644 --- a/app/code/Magento/CatalogInventory/Helper/Stock.php +++ b/app/code/Magento/CatalogInventory/Helper/Stock.php @@ -19,8 +19,9 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Stock { diff --git a/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php index 29f7aa61ab8b1..145b0d1454ae2 100644 --- a/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php +++ b/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php @@ -21,8 +21,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Item extends \Magento\CatalogInventory\Model\Stock\Item implements IdentityInterface { diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php index c13a2560c6ac2..502d9532e8a05 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php @@ -26,8 +26,9 @@ * @since 100.0.2 * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class QuantityValidator { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php index ef43010826523..ba3b62f554767 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php @@ -19,8 +19,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class DefaultStock extends AbstractIndexer implements StockInterface { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php index a24a10d7433c2..115002b237645 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/QueryProcessorInterface.php @@ -12,8 +12,9 @@ * @api * @since 100.1.0 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface QueryProcessorInterface { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php index 3f0523e8fba6c..24ed496372817 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/StockInterface.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ interface StockInterface { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php index fae1ee72ac34f..0ee162e429f40 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/StockFactory.php @@ -13,8 +13,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class StockFactory { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php index 1e826ef229f13..402ce5f2f611e 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php @@ -14,8 +14,9 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { diff --git a/app/code/Magento/CatalogInventory/Model/Source/Backorders.php b/app/code/Magento/CatalogInventory/Model/Source/Backorders.php index b13f7e570d859..0bffb9a9888cd 100644 --- a/app/code/Magento/CatalogInventory/Model/Source/Backorders.php +++ b/app/code/Magento/CatalogInventory/Model/Source/Backorders.php @@ -10,8 +10,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Backorders implements \Magento\Framework\Option\ArrayInterface { diff --git a/app/code/Magento/CatalogInventory/Model/Source/Stock.php b/app/code/Magento/CatalogInventory/Model/Source/Stock.php index 992709419fa25..7d44ab782de61 100644 --- a/app/code/Magento/CatalogInventory/Model/Source/Stock.php +++ b/app/code/Magento/CatalogInventory/Model/Source/Stock.php @@ -12,8 +12,9 @@ * @api * @since 100.0.2 * - * @deprecated CatalogInventory will be replaced by Multi-Source Inventory (MSI) - * see https://devdocs.magento.com/guides/v2.3/rest/modules/inventory/inventory.html + * @deprecated 2.3.0 Replaced with Multi Source Inventory + * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html + * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html */ class Stock extends AbstractSource { From f87301a5e6b77078db23eac82efc9338ee63859d Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Thu, 18 Oct 2018 13:13:21 -0500 Subject: [PATCH 370/812] MAGETWO-95532: Unable to upload image from TinyMCE3 --- .../Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php b/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php index 7e60039e86880..ee9087e082a56 100644 --- a/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php +++ b/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php @@ -22,6 +22,7 @@ class CompositeConfigProviderTest extends \PHPUnit\Framework\TestCase * @return void * * @magentoConfigFixture default/cms/wysiwyg/editor Magento_Tinymce3/tinymce3Adapter + * @magentoAppIsolation enabled */ public function testTestModuleEnabledModuleIsAbleToModifyConfig() { From e058daaa665d8b3b98b652178adb89b0ef4a7155 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Thu, 18 Oct 2018 13:16:34 -0500 Subject: [PATCH 371/812] MAGETWO-95532: Unable to upload image from TinyMCE3 --- .../Wysiwyg/CompositeConfigProviderTest.php | 45 ------------------- 1 file changed, 45 deletions(-) delete mode 100644 dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php diff --git a/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php b/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.php deleted file mode 100644 index ee9087e082a56..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Tinymce3/Model/Wysiwyg/CompositeConfigProviderTest.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\Tinymce3\Model\Wysiwyg; - -use Magento\TestFramework\Helper\Bootstrap; -use Magento\Framework\AuthorizationInterface; - -/** - * @magentoAppArea adminhtml - */ -class CompositeConfigProviderTest extends \PHPUnit\Framework\TestCase -{ - /** - * Test enabled module is able to modify WYSIWYG config - * - * @return void - * - * @magentoConfigFixture default/cms/wysiwyg/editor Magento_Tinymce3/tinymce3Adapter - * @magentoAppIsolation enabled - */ - public function testTestModuleEnabledModuleIsAbleToModifyConfig() - { - $objectManager = Bootstrap::getObjectManager(); - $objectManager->configure([ - 'preferences' => [ - AuthorizationInterface::class => \Magento\Backend\Model\Search\AuthorizationMock::class - ] - ]); - $compositeConfigProvider = $objectManager->create(\Magento\Cms\Model\Wysiwyg\CompositeConfigProvider::class); - $model = $objectManager->create( - \Magento\Cms\Model\Wysiwyg\Config::class, - ['configProvider' => $compositeConfigProvider] - ); - $config = $model->getConfig(); - $this->assertArrayHasKey('add_images', $config); - $this->assertArrayHasKey('files_browser_window_url', $config); - $this->assertTrue($config['add_images']); - } -} From 41b1834c12f0529cc171ee5eca7d304afddc13c2 Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk <kolesnyk@adobe.com> Date: Thu, 18 Oct 2018 14:19:26 -0500 Subject: [PATCH 372/812] Update Product type switching test --- .../Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml index 460cc29b183e0..8fbb64f4579b1 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml @@ -33,6 +33,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> </variation> <variation name="ProductTypeSwitchingOnCreationTestVariation4"> + <data name="issue" xsi:type="string">MSI-1624</data> <data name="createProduct" xsi:type="string">configurable</data> <data name="product" xsi:type="string">catalogProductVirtual::required_fields</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> From c83a1caa6b1eb7182f235310938c22cfea7826f4 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 19 Oct 2018 11:58:59 +0300 Subject: [PATCH 373/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- app/code/Magento/Catalog/etc/adminhtml/system.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/etc/adminhtml/system.xml b/app/code/Magento/Catalog/etc/adminhtml/system.xml index 1b0fe4c85f617..7478fa2226454 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/system.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/system.xml @@ -206,7 +206,7 @@ <label>Images Upload Configuration</label> <field id="jpeg_quality" translate="label comment" type="text" sortOrder="100" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Quality</label> - <validate>validate-greater-than-zero validate-digits validate-range required-entry digits-range-1-100</validate> + <validate>validate-digits validate-digits-range digits-range-1-100 required-entry</validate> <comment>Jpeg quality for resized images 1-100%.</comment> </field> </group> From 8433083f3c6a0c33500d7ad1ce7ead82c59a9cfe Mon Sep 17 00:00:00 2001 From: Timon de Groot <timon@marissen.net> Date: Fri, 19 Oct 2018 11:55:18 +0200 Subject: [PATCH 374/812] Restructure estimate-service.js --- .../web/js/model/cart/estimate-service.js | 101 ++++++++++-------- 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js index 76e3d911e7d3f..f1da0ed7916e7 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js @@ -14,55 +14,70 @@ define([ 'use strict'; var rateProcessors = [], - totalsProcessors = []; + totalsProcessors = [], - quote.shippingAddress.subscribe(function () { - var type = quote.shippingAddress().getType(); + /** + * Estimate totals for shipping address and update shipping rates. + */ + estimateTotalsAndUpdateRates = function() { + var type = quote.shippingAddress().getType(); - if ( - quote.isVirtual() || - window.checkoutConfig.activeCarriers && window.checkoutConfig.activeCarriers.length === 0 - ) { - // update totals block when estimated address was set - totalsProcessors['default'] = totalsDefaultProvider; - totalsProcessors[type] ? - totalsProcessors[type].estimateTotals(quote.shippingAddress()) : - totalsProcessors['default'].estimateTotals(quote.shippingAddress()); - } else { - // check if user data not changed -> load rates from cache - if (!cartCache.isChanged('address', quote.shippingAddress()) && - !cartCache.isChanged('cartVersion', customerData.get('cart')()['data_id']) && - cartCache.get('rates') + if ( + quote.isVirtual() || + window.checkoutConfig.activeCarriers && window.checkoutConfig.activeCarriers.length === 0 ) { - shippingService.setShippingRates(cartCache.get('rates')); + // update totals block when estimated address was set + totalsProcessors['default'] = totalsDefaultProvider; + totalsProcessors[type] ? + totalsProcessors[type].estimateTotals(quote.shippingAddress()) : + totalsProcessors['default'].estimateTotals(quote.shippingAddress()); + } else { + // check if user data not changed -> load rates from cache + if (!cartCache.isChanged('address', quote.shippingAddress()) && + !cartCache.isChanged('cartVersion', customerData.get('cart')()['data_id']) && + cartCache.get('rates') + ) { + shippingService.setShippingRates(cartCache.get('rates')); - return; + return; + } + + // update rates list when estimated address was set + rateProcessors['default'] = defaultProcessor; + rateProcessors[type] ? + rateProcessors[type].getRates(quote.shippingAddress()) : + rateProcessors['default'].getRates(quote.shippingAddress()); + + // save rates to cache after load + shippingService.getShippingRates().subscribe(function (rates) { + cartCache.set('rates', rates); + }); } + }, - // update rates list when estimated address was set - rateProcessors['default'] = defaultProcessor; - rateProcessors[type] ? - rateProcessors[type].getRates(quote.shippingAddress()) : - rateProcessors['default'].getRates(quote.shippingAddress()); + /** + * Estimate totals for shipping address. + */ + estimateTotalsShipping = function() { + totalsDefaultProvider.estimateTotals(quote.shippingAddress()); + }, - // save rates to cache after load - shippingService.getShippingRates().subscribe(function (rates) { - cartCache.set('rates', rates); - }); - } - }); - quote.shippingMethod.subscribe(function () { - totalsDefaultProvider.estimateTotals(quote.shippingAddress()); - }); - quote.billingAddress.subscribe(function () { - var type = quote.billingAddress().getType(); + /** + * Estimate totals for billing address. + */ + estimateTotalsBilling = function() { + var type = quote.billingAddress().getType(); + + if (quote.isVirtual()) { + // update totals block when estimated address was set + totalsProcessors['default'] = totalsDefaultProvider; + totalsProcessors[type] ? + totalsProcessors[type].estimateTotals(quote.billingAddress()) : + totalsProcessors['default'].estimateTotals(quote.billingAddress()); + } + }; - if (quote.isVirtual()) { - // update totals block when estimated address was set - totalsProcessors['default'] = totalsDefaultProvider; - totalsProcessors[type] ? - totalsProcessors[type].estimateTotals(quote.billingAddress()) : - totalsProcessors['default'].estimateTotals(quote.billingAddress()); - } - }); + quote.shippingAddress.subscribe(estimateTotalsAndUpdateRates); + quote.shippingMethod.subscribe(estimateTotalsShipping); + quote.billingAddress.subscribe(estimateTotalsBilling); }); From 4fd6a03fe5367032b30c0c828246756d8f1db24c Mon Sep 17 00:00:00 2001 From: Timon de Groot <timon@marissen.net> Date: Fri, 19 Oct 2018 11:55:55 +0200 Subject: [PATCH 375/812] Estimate totals when cart data changes --- .../Checkout/view/frontend/web/js/model/cart/estimate-service.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js index f1da0ed7916e7..f85a1385e0815 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js @@ -80,4 +80,5 @@ define([ quote.shippingAddress.subscribe(estimateTotalsAndUpdateRates); quote.shippingMethod.subscribe(estimateTotalsShipping); quote.billingAddress.subscribe(estimateTotalsBilling); + customerData.get('cart').subscribe(estimateTotalsShipping); }); From 031d8ec39d2350054b6aa2f0cabe338c0b35bb00 Mon Sep 17 00:00:00 2001 From: Graham Wharton <graham@gwharton.me.uk> Date: Fri, 19 Oct 2018 11:39:21 +0100 Subject: [PATCH 376/812] Forwardport of MAGETWO-93818: Magnifier function does not disappear after mouse-off the image from the bottom Added onMouseLeave events --- lib/web/magnifier/magnifier.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/web/magnifier/magnifier.js b/lib/web/magnifier/magnifier.js index 150c8adf0b22b..b48ffa6f50b18 100644 --- a/lib/web/magnifier/magnifier.js +++ b/lib/web/magnifier/magnifier.js @@ -554,6 +554,15 @@ thumbObj.src = thumb.src; } + /** + * Hide magnifier when mouse exceeds image bounds. + */ + function onMouseLeave() { + onThumbLeave(); + isOverThumb = false; + $magnifierPreview.addClass(MagnifyCls.magnifyHidden); + } + function onMousemove(e) { pos.x = e.clientX; pos.y = e.clientY; @@ -564,15 +573,9 @@ isOverThumb = inBounds; } - if (inBounds && isOverThumb) { - if(gMode === 'outside'){ - $magnifierPreview.removeClass(MagnifyCls.magnifyHidden); - } + if (inBounds && isOverThumb && gMode === 'outside') { + $magnifierPreview.removeClass(MagnifyCls.magnifyHidden); move(); - } else { - onThumbLeave(); - isOverThumb = false; - $magnifierPreview.addClass(MagnifyCls.magnifyHidden); } } @@ -589,6 +592,8 @@ }); $box.on('mousemove', onMousemove); + $box.on('mouseleave', onMouseLeave); + _init($box, customUserOptions); } }(jQuery)); From 9688034346f5b322b9767ab6af5c8163e67b28ac Mon Sep 17 00:00:00 2001 From: Jakub Idziak <j.idziak@macopedia.pl> Date: Thu, 18 Oct 2018 16:13:36 +0200 Subject: [PATCH 377/812] ISSUE-5021 - fixed place order for custom shipping methods with underscore in carrier code --- .../Magento/Checkout/Model/PaymentInformationManagement.php | 5 ++--- .../Test/Unit/Model/PaymentInformationManagementTest.php | 5 ++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php index 164109177d4e9..947f7b896f67a 100644 --- a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php +++ b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php @@ -115,9 +115,8 @@ public function savePaymentInformation( $quote->setDataChanges(true); $shippingAddress = $quote->getShippingAddress(); if ($shippingAddress && $shippingAddress->getShippingMethod()) { - $shippingDataArray = explode('_', $shippingAddress->getShippingMethod()); - $shippingCarrier = array_shift($shippingDataArray); - $shippingAddress->setLimitCarrier($shippingCarrier); + $shippingRate = $shippingAddress->getShippingRateByCode($shippingAddress->getShippingMethod()); + $shippingAddress->setLimitCarrier($shippingRate->getCarrier()); } } $this->paymentMethodManagement->set($cartId, $paymentMethod); diff --git a/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php index 77c15fccfa8ae..ea841e86586ba 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php @@ -172,9 +172,11 @@ private function getMockForAssignBillingAddress($cartId, $billingAddressMock) $billingAddressId = 1; $quoteMock = $this->createMock(\Magento\Quote\Model\Quote::class); $quoteBillingAddress = $this->createMock(\Magento\Quote\Model\Quote\Address::class); + $shippingRate = $this->createPartialMock(\Magento\Quote\Model\Quote\Address\Rate::class, []); + $shippingRate->setCarrier('flatrate'); $quoteShippingAddress = $this->createPartialMock( \Magento\Quote\Model\Quote\Address::class, - ['setLimitCarrier', 'getShippingMethod'] + ['setLimitCarrier', 'getShippingMethod', 'getShippingRateByCode'] ); $this->cartRepositoryMock->expects($this->any())->method('getActive')->with($cartId)->willReturn($quoteMock); $quoteMock->expects($this->once())->method('getBillingAddress')->willReturn($quoteBillingAddress); @@ -183,6 +185,7 @@ private function getMockForAssignBillingAddress($cartId, $billingAddressMock) $quoteMock->expects($this->once())->method('removeAddress')->with($billingAddressId); $quoteMock->expects($this->once())->method('setBillingAddress')->with($billingAddressMock); $quoteMock->expects($this->once())->method('setDataChanges')->willReturnSelf(); + $quoteShippingAddress->expects($this->any())->method('getShippingRateByCode')->willReturn($shippingRate); $quoteShippingAddress->expects($this->any())->method('getShippingMethod')->willReturn('flatrate_flatrate'); $quoteShippingAddress->expects($this->once())->method('setLimitCarrier')->with('flatrate')->willReturnSelf(); } From 4b76ffdc54c19f0fe642761540120744b8d0fc43 Mon Sep 17 00:00:00 2001 From: Graham Wharton <graham@gwharton.me.uk> Date: Fri, 19 Oct 2018 12:17:36 +0100 Subject: [PATCH 378/812] Fixed whitespace issue --- lib/web/magnifier/magnifier.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/magnifier/magnifier.js b/lib/web/magnifier/magnifier.js index b48ffa6f50b18..0807a4c394995 100644 --- a/lib/web/magnifier/magnifier.js +++ b/lib/web/magnifier/magnifier.js @@ -593,7 +593,7 @@ $box.on('mousemove', onMousemove); $box.on('mouseleave', onMouseLeave); - + _init($box, customUserOptions); } }(jQuery)); From 7584f715e27ec3fb6d7dcf6511999f27466e35ae Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Fri, 19 Oct 2018 08:01:01 -0400 Subject: [PATCH 379/812] Allow set billing information via API with existing address Not setting the customerId with an existing address caused a `NoSuchEntityException` to be thrown during address validation https://github.com/magento/magento2/blob/56af1e73ce21867b770a7458ab6e109f4a1eface/app/code/Magento/Quote/Model/QuoteAddressValidator.php#L84 Fixes #17485 --- app/code/Magento/Quote/Model/BillingAddressManagement.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Quote/Model/BillingAddressManagement.php b/app/code/Magento/Quote/Model/BillingAddressManagement.php index 70a8c94fefad0..e8af185b8c2f0 100644 --- a/app/code/Magento/Quote/Model/BillingAddressManagement.php +++ b/app/code/Magento/Quote/Model/BillingAddressManagement.php @@ -77,6 +77,7 @@ public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $addres { /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); + $address->setCustomerId($quote->getCustomerId()); $quote->removeAddress($quote->getBillingAddress()->getId()); $quote->setBillingAddress($address); try { From 9a249e97c4a645f513a1f0aaaeed5957689c8e7f Mon Sep 17 00:00:00 2001 From: Timon de Groot <timon@marissen.net> Date: Fri, 19 Oct 2018 14:02:15 +0200 Subject: [PATCH 380/812] Fix js static error --- .../view/frontend/web/js/model/cart/estimate-service.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js index f85a1385e0815..54e496131972e 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js @@ -19,7 +19,7 @@ define([ /** * Estimate totals for shipping address and update shipping rates. */ - estimateTotalsAndUpdateRates = function() { + estimateTotalsAndUpdateRates = function () { var type = quote.shippingAddress().getType(); if ( @@ -58,14 +58,14 @@ define([ /** * Estimate totals for shipping address. */ - estimateTotalsShipping = function() { + estimateTotalsShipping = function () { totalsDefaultProvider.estimateTotals(quote.shippingAddress()); }, /** * Estimate totals for billing address. */ - estimateTotalsBilling = function() { + estimateTotalsBilling = function () { var type = quote.billingAddress().getType(); if (quote.isVirtual()) { From c3e4b0414e703d04934584792daf948d844305ba Mon Sep 17 00:00:00 2001 From: Timon de Groot <timon@marissen.net> Date: Fri, 19 Oct 2018 14:16:39 +0200 Subject: [PATCH 381/812] Add test for cart data mutations/estimation call --- .../Checkout/frontend/js/model/cart/estimate-service.test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js index 3d8325a3ecd54..31009555bd9f9 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js @@ -150,5 +150,10 @@ define([ }); expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals).toHaveBeenCalled(); }); + + it('test subscribe when cart data was changed', function () { + mocks['Magento_Customer/js/customer-data'].get('cart')({ data_id: 2 }); + expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals).toHaveBeenCalled(); + }); }); }); From 0afc6c64ccb4af80b658c8c266a9f573e30ae8d5 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 19 Oct 2018 08:59:39 -0500 Subject: [PATCH 382/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../AdminNotification/etc/db_schema.xml | 10 +- .../Magento/AdvancedSearch/etc/db_schema.xml | 6 +- .../AsynchronousOperations/etc/db_schema.xml | 18 +- .../Magento/Authorization/etc/db_schema.xml | 14 +- app/code/Magento/Bundle/etc/db_schema.xml | 56 +- app/code/Magento/Captcha/etc/db_schema.xml | 2 +- app/code/Magento/Catalog/etc/db_schema.xml | 532 +++++++++--------- .../CatalogInventory/etc/db_schema.xml | 44 +- .../Magento/CatalogRule/etc/db_schema.xml | 80 +-- .../CatalogUrlRewrite/etc/db_schema.xml | 8 +- .../CheckoutAgreements/etc/db_schema.xml | 8 +- app/code/Magento/Cms/etc/db_schema.xml | 26 +- app/code/Magento/Config/etc/db_schema.xml | 4 +- .../ConfigurableProduct/etc/db_schema.xml | 26 +- app/code/Magento/Cron/etc/db_schema.xml | 6 +- app/code/Magento/Customer/etc/db_schema.xml | 168 +++--- app/code/Magento/Directory/etc/db_schema.xml | 20 +- .../Magento/Downloadable/etc/db_schema.xml | 70 +-- app/code/Magento/Eav/etc/db_schema.xml | 212 +++---- app/code/Magento/Email/etc/db_schema.xml | 8 +- .../Magento/GiftMessage/etc/db_schema.xml | 2 +- .../Magento/GoogleOptimizer/etc/db_schema.xml | 6 +- .../Magento/ImportExport/etc/db_schema.xml | 4 +- app/code/Magento/Indexer/etc/db_schema.xml | 10 +- .../Magento/Integration/etc/db_schema.xml | 40 +- .../Magento/MessageQueue/etc/db_schema.xml | 4 +- app/code/Magento/MysqlMq/etc/db_schema.xml | 16 +- .../NewRelicReporting/etc/db_schema.xml | 10 +- app/code/Magento/Newsletter/etc/db_schema.xml | 52 +- .../Magento/OfflineShipping/etc/db_schema.xml | 4 +- app/code/Magento/Paypal/etc/db_schema.xml | 38 +- app/code/Magento/Persistent/etc/db_schema.xml | 12 +- .../Magento/ProductAlert/etc/db_schema.xml | 28 +- .../Magento/ProductVideo/etc/db_schema.xml | 6 +- app/code/Magento/Quote/etc/db_schema.xml | 70 +-- .../ReleaseNotification/etc/db_schema.xml | 6 +- app/code/Magento/Reports/etc/db_schema.xml | 90 +-- app/code/Magento/Review/etc/db_schema.xml | 96 ++-- app/code/Magento/Sales/etc/db_schema.xml | 426 +++++++------- app/code/Magento/SalesRule/etc/db_schema.xml | 104 ++-- .../Magento/SalesSequence/etc/db_schema.xml | 10 +- app/code/Magento/Search/etc/db_schema.xml | 24 +- app/code/Magento/Security/etc/db_schema.xml | 14 +- app/code/Magento/SendFriend/etc/db_schema.xml | 6 +- app/code/Magento/Signifyd/etc/db_schema.xml | 8 +- app/code/Magento/Sitemap/etc/db_schema.xml | 6 +- app/code/Magento/Store/etc/db_schema.xml | 32 +- app/code/Magento/Swatches/etc/db_schema.xml | 10 +- app/code/Magento/Tax/etc/db_schema.xml | 60 +- app/code/Magento/Theme/etc/db_schema.xml | 12 +- .../Magento/Translation/etc/db_schema.xml | 6 +- app/code/Magento/Ui/etc/db_schema.xml | 6 +- app/code/Magento/UrlRewrite/etc/db_schema.xml | 8 +- app/code/Magento/User/etc/db_schema.xml | 10 +- app/code/Magento/Variable/etc/db_schema.xml | 14 +- app/code/Magento/Vault/etc/db_schema.xml | 14 +- app/code/Magento/Weee/etc/db_schema.xml | 18 +- app/code/Magento/Widget/etc/db_schema.xml | 38 +- app/code/Magento/Wishlist/etc/db_schema.xml | 26 +- app/etc/db_schema.xml | 2 +- app/etc/di.xml | 21 + .../Declaration/Schema/Config/Converter.php | 51 +- .../Schema/Config/SchemaLocator.php | 60 -- .../Schema/Declaration/SchemaBuilder.php | 62 +- .../Schema/FileSystem/XmlReader.php | 63 --- .../Schema/etc/constraints/constraint.xsd | 2 +- .../Setup/Declaration/Schema/etc/index.xsd | 2 +- .../Setup/Declaration/Schema/etc/name.xsd | 14 + .../Setup/Declaration/Schema/etc/schema.xsd | 2 +- 69 files changed, 1441 insertions(+), 1502 deletions(-) delete mode 100644 lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/SchemaLocator.php delete mode 100644 lib/internal/Magento/Framework/Setup/Declaration/Schema/FileSystem/XmlReader.php diff --git a/app/code/Magento/AdminNotification/etc/db_schema.xml b/app/code/Magento/AdminNotification/etc/db_schema.xml index 35e6045b607d1..29d928ced2084 100644 --- a/app/code/Magento/AdminNotification/etc/db_schema.xml +++ b/app/code/Magento/AdminNotification/etc/db_schema.xml @@ -21,16 +21,16 @@ default="0" comment="Flag if notification read"/> <column xsi:type="smallint" name="is_remove" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Flag if notification might be removed"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="notification_id"/> </constraint> - <index name="ADMINNOTIFICATION_INBOX_SEVERITY" indexType="btree"> + <index referenceId="ADMINNOTIFICATION_INBOX_SEVERITY" indexType="btree"> <column name="severity"/> </index> - <index name="ADMINNOTIFICATION_INBOX_IS_READ" indexType="btree"> + <index referenceId="ADMINNOTIFICATION_INBOX_IS_READ" indexType="btree"> <column name="is_read"/> </index> - <index name="ADMINNOTIFICATION_INBOX_IS_REMOVE" indexType="btree"> + <index referenceId="ADMINNOTIFICATION_INBOX_IS_REMOVE" indexType="btree"> <column name="is_remove"/> </index> </table> @@ -40,7 +40,7 @@ default="0" comment="Problem type"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Create date"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="identity"/> </constraint> </table> diff --git a/app/code/Magento/AdvancedSearch/etc/db_schema.xml b/app/code/Magento/AdvancedSearch/etc/db_schema.xml index 9fae40411098c..2dd8c68e2d5fd 100644 --- a/app/code/Magento/AdvancedSearch/etc/db_schema.xml +++ b/app/code/Magento/AdvancedSearch/etc/db_schema.xml @@ -14,13 +14,13 @@ default="0" comment="Query Id"/> <column xsi:type="int" name="relation_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Relation Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="CATALOGSEARCH_RECOMMENDATIONS_QUERY_ID_SEARCH_QUERY_QUERY_ID" + <constraint xsi:type="foreign" referenceId="CATALOGSEARCH_RECOMMENDATIONS_QUERY_ID_SEARCH_QUERY_QUERY_ID" table="catalogsearch_recommendations" column="query_id" referenceTable="search_query" referenceColumn="query_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOGSEARCH_RECOMMENDATIONS_RELATION_ID_SEARCH_QUERY_QUERY_ID" + <constraint xsi:type="foreign" referenceId="CATALOGSEARCH_RECOMMENDATIONS_RELATION_ID_SEARCH_QUERY_QUERY_ID" table="catalogsearch_recommendations" column="relation_id" referenceTable="search_query" referenceColumn="query_id" onDelete="CASCADE"/> </table> diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml index 342326e6666f1..5cd55408838fe 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml @@ -21,13 +21,13 @@ comment="Total number of operations scheduled within this bulk"/> <column xsi:type="timestamp" name="start_time" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Bulk start time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="unique" name="MAGENTO_BULK_UUID"> + <constraint xsi:type="unique" referenceId="MAGENTO_BULK_UUID"> <column name="uuid"/> </constraint> - <index name="MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID" indexType="btree"> + <index referenceId="MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID" indexType="btree"> <column name="user_id"/> </index> </table> @@ -47,12 +47,12 @@ comment="Code of the error that appeared during operation execution (used to aggregate related failed operations)"/> <column xsi:type="varchar" name="result_message" nullable="true" length="255" comment="Operation result message"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="MAGENTO_OPERATION_BULK_UUID_MAGENTO_BULK_UUID" table="magento_operation" + <constraint xsi:type="foreign" referenceId="MAGENTO_OPERATION_BULK_UUID_MAGENTO_BULK_UUID" table="magento_operation" column="bulk_uuid" referenceTable="magento_bulk" referenceColumn="uuid" onDelete="CASCADE"/> - <index name="MAGENTO_OPERATION_BULK_UUID_ERROR_CODE" indexType="btree"> + <index referenceId="MAGENTO_OPERATION_BULK_UUID_ERROR_CODE" indexType="btree"> <column name="bulk_uuid"/> <column name="error_code"/> </index> @@ -62,13 +62,13 @@ <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="Internal ID"/> <column xsi:type="varbinary" name="bulk_uuid" nullable="true" length="39" comment="Related Bulk UUID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID_MAGENTO_BULK_UUID" + <constraint xsi:type="foreign" referenceId="MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID_MAGENTO_BULK_UUID" table="magento_acknowledged_bulk" column="bulk_uuid" referenceTable="magento_bulk" referenceColumn="uuid" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID"> + <constraint xsi:type="unique" referenceId="MAGENTO_ACKNOWLEDGED_BULK_BULK_UUID"> <column name="bulk_uuid"/> </constraint> </table> diff --git a/app/code/Magento/Authorization/etc/db_schema.xml b/app/code/Magento/Authorization/etc/db_schema.xml index 45c02128bfc99..a38828eb6efca 100644 --- a/app/code/Magento/Authorization/etc/db_schema.xml +++ b/app/code/Magento/Authorization/etc/db_schema.xml @@ -21,14 +21,14 @@ comment="User ID"/> <column xsi:type="varchar" name="user_type" nullable="true" length="16" comment="User Type"/> <column xsi:type="varchar" name="role_name" nullable="true" length="50" comment="Role Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="role_id"/> </constraint> - <index name="AUTHORIZATION_ROLE_PARENT_ID_SORT_ORDER" indexType="btree"> + <index referenceId="AUTHORIZATION_ROLE_PARENT_ID_SORT_ORDER" indexType="btree"> <column name="parent_id"/> <column name="sort_order"/> </index> - <index name="AUTHORIZATION_ROLE_TREE_LEVEL" indexType="btree"> + <index referenceId="AUTHORIZATION_ROLE_TREE_LEVEL" indexType="btree"> <column name="tree_level"/> </index> </table> @@ -40,17 +40,17 @@ <column xsi:type="varchar" name="resource_id" nullable="true" length="255" comment="Resource ID"/> <column xsi:type="varchar" name="privileges" nullable="true" length="20" comment="Privileges"/> <column xsi:type="varchar" name="permission" nullable="true" length="10" comment="Permission"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> </constraint> - <constraint xsi:type="foreign" name="AUTHORIZATION_RULE_ROLE_ID_AUTHORIZATION_ROLE_ROLE_ID" + <constraint xsi:type="foreign" referenceId="AUTHORIZATION_RULE_ROLE_ID_AUTHORIZATION_ROLE_ROLE_ID" table="authorization_rule" column="role_id" referenceTable="authorization_role" referenceColumn="role_id" onDelete="CASCADE"/> - <index name="AUTHORIZATION_RULE_RESOURCE_ID_ROLE_ID" indexType="btree"> + <index referenceId="AUTHORIZATION_RULE_RESOURCE_ID_ROLE_ID" indexType="btree"> <column name="resource_id"/> <column name="role_id"/> </index> - <index name="AUTHORIZATION_RULE_ROLE_ID_RESOURCE_ID" indexType="btree"> + <index referenceId="AUTHORIZATION_RULE_ROLE_ID_RESOURCE_ID" indexType="btree"> <column name="role_id"/> <column name="resource_id"/> </index> diff --git a/app/code/Magento/Bundle/etc/db_schema.xml b/app/code/Magento/Bundle/etc/db_schema.xml index 8092f34c533fa..6ff779518d34c 100644 --- a/app/code/Magento/Bundle/etc/db_schema.xml +++ b/app/code/Magento/Bundle/etc/db_schema.xml @@ -18,13 +18,13 @@ <column xsi:type="int" name="position" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Position"/> <column xsi:type="varchar" name="type" nullable="true" length="255" comment="Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_OPT_PARENT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_OPT_PARENT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_bundle_option" column="parent_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_BUNDLE_OPTION_PARENT_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_BUNDLE_OPTION_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -39,13 +39,13 @@ <column xsi:type="varchar" name="title" nullable="true" length="255" comment="Title"/> <column xsi:type="int" name="parent_product_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Parent Product Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_OPT_VAL_OPT_ID_CAT_PRD_BNDL_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_OPT_VAL_OPT_ID_CAT_PRD_BNDL_OPT_OPT_ID" table="catalog_product_bundle_option_value" column="option_id" referenceTable="catalog_product_bundle_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_BNDL_OPT_VAL_OPT_ID_PARENT_PRD_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_BNDL_OPT_VAL_OPT_ID_PARENT_PRD_ID_STORE_ID"> <column name="option_id"/> <column name="parent_product_id"/> <column name="store_id"/> @@ -73,19 +73,19 @@ comment="Selection Qty"/> <column xsi:type="smallint" name="selection_can_change_qty" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Selection Can Change Qty"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="selection_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_SELECTION_OPT_ID_CAT_PRD_BNDL_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_SELECTION_OPT_ID_CAT_PRD_BNDL_OPT_OPT_ID" table="catalog_product_bundle_selection" column="option_id" referenceTable="catalog_product_bundle_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_SELECTION_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_SELECTION_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_bundle_selection" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_BUNDLE_SELECTION_OPTION_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_BUNDLE_SELECTION_OPTION_ID" indexType="btree"> <column name="option_id"/> </index> - <index name="CATALOG_PRODUCT_BUNDLE_SELECTION_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_BUNDLE_SELECTION_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -101,19 +101,19 @@ nullable="false" default="0" comment="Selection Price Value"/> <column xsi:type="int" name="parent_product_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Parent Product Id"/> - <constraint xsi:type="primary" name="PK_CATALOG_PRODUCT_BUNDLE_SELECTION_PRICE"> + <constraint xsi:type="primary" referenceId="PK_CATALOG_PRODUCT_BUNDLE_SELECTION_PRICE"> <column name="selection_id"/> <column name="parent_product_id"/> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_SELECTION_PRICE_WS_ID_STORE_WS_WS_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_SELECTION_PRICE_WS_ID_STORE_WS_WS_ID" table="catalog_product_bundle_selection_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_DCF37523AA05D770A70AA4ED7C2616E4" + <constraint xsi:type="foreign" referenceId="FK_DCF37523AA05D770A70AA4ED7C2616E4" table="catalog_product_bundle_selection_price" column="selection_id" referenceTable="catalog_product_bundle_selection" referenceColumn="selection_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_BUNDLE_SELECTION_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_BUNDLE_SELECTION_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -129,24 +129,24 @@ comment="Min Price"/> <column xsi:type="decimal" name="max_price" scale="4" precision="12" unsigned="false" nullable="false" comment="Max Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="website_id"/> <column name="customer_group_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_PRICE_IDX_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_PRICE_IDX_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" table="catalog_product_bundle_price_index" column="customer_group_id" referenceTable="customer_group" referenceColumn="customer_group_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_PRICE_IDX_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_PRICE_IDX_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_bundle_price_index" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_BNDL_PRICE_IDX_WS_ID_STORE_WS_WS_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_BNDL_PRICE_IDX_WS_ID_STORE_WS_WS_ID" table="catalog_product_bundle_price_index" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_BUNDLE_PRICE_INDEX_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_BUNDLE_PRICE_INDEX_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOG_PRODUCT_BUNDLE_PRICE_INDEX_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_BUNDLE_PRICE_INDEX_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> </table> @@ -162,7 +162,7 @@ default="0" comment="Option Id"/> <column xsi:type="smallint" name="stock_status" padding="6" unsigned="false" nullable="true" identity="false" default="0" comment="Stock Status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="website_id"/> <column name="stock_id"/> @@ -197,7 +197,7 @@ comment="Tier Price"/> <column xsi:type="decimal" name="base_tier" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Tier"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -231,7 +231,7 @@ comment="Tier Price"/> <column xsi:type="decimal" name="base_tier" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Tier"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -257,7 +257,7 @@ comment="Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -285,7 +285,7 @@ comment="Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -313,7 +313,7 @@ comment="Tier Price"/> <column xsi:type="decimal" name="alt_tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Alt Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -340,7 +340,7 @@ comment="Tier Price"/> <column xsi:type="decimal" name="alt_tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Alt Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> diff --git a/app/code/Magento/Captcha/etc/db_schema.xml b/app/code/Magento/Captcha/etc/db_schema.xml index fa9a14abb8963..b8987363569ca 100644 --- a/app/code/Magento/Captcha/etc/db_schema.xml +++ b/app/code/Magento/Captcha/etc/db_schema.xml @@ -13,7 +13,7 @@ <column xsi:type="int" name="count" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Count"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="true" comment="Update Time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="type"/> <column name="value"/> </constraint> diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index 7b4e1a96adda0..07378f6a27fec 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -22,13 +22,13 @@ comment="Creation Time"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Update Time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_ATTRIBUTE_SET_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_ATTRIBUTE_SET_ID" indexType="btree"> <column name="attribute_set_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_SKU" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_SKU" indexType="btree"> <column name="sku"/> </index> </table> @@ -43,27 +43,27 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0"/> <column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_datetime" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_DTIME_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DTIME_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_datetime" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_datetime" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -79,27 +79,27 @@ default="0"/> <column xsi:type="decimal" name="value" scale="4" precision="12" unsigned="false" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_DEC_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DEC_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_decimal" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_DEC_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DEC_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_decimal" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_ENTITY_DECIMAL_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_DECIMAL_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_decimal" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_DECIMAL_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_DECIMAL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -115,27 +115,27 @@ default="0"/> <column xsi:type="int" name="value" padding="11" unsigned="false" nullable="true" identity="false" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_INT_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_INT_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_int" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_INT_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_INT_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_int" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_ENTITY_INT_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_INT_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_int" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_INT_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_INT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -150,27 +150,27 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0"/> <column xsi:type="text" name="value" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_TEXT_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_TEXT_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_text" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_TEXT_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_TEXT_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_text" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_ENTITY_TEXT_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_TEXT_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_text" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_TEXT_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_TEXT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -185,27 +185,27 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_varchar" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_VCHR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_VCHR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_varchar" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_varchar" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -222,30 +222,30 @@ <column xsi:type="int" name="position" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Position"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_GLR_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_GLR_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_gallery" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_GLR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_GLR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_gallery" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_ENTITY_GALLERY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_GALLERY_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_gallery" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_ENTITY_GALLERY_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_GALLERY_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_GALLERY_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_GALLERY_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_GALLERY_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_GALLERY_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_GALLERY_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_GALLERY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -267,13 +267,13 @@ comment="Tree Level"/> <column xsi:type="int" name="children_count" padding="11" unsigned="false" nullable="false" identity="false" comment="Child Count"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <index name="CATALOG_CATEGORY_ENTITY_LEVEL" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_LEVEL" indexType="btree"> <column name="level"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_PATH" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_PATH" indexType="btree"> <column name="path"/> </index> </table> @@ -288,30 +288,30 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0"/> <column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_category_entity_datetime" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_DTIME_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_DTIME_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_category_entity_datetime" column="entity_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_CATEGORY_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_CATEGORY_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" table="catalog_category_entity_datetime" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_CATEGORY_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_CATEGORY_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_CATEGORY_ENTITY_DATETIME_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_DATETIME_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_DATETIME_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_DATETIME_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -327,30 +327,30 @@ default="0"/> <column xsi:type="decimal" name="value" scale="4" precision="12" unsigned="false" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_DEC_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_DEC_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_category_entity_decimal" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_DEC_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_DEC_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_category_entity_decimal" column="entity_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_CATEGORY_ENTITY_DECIMAL_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_CATEGORY_ENTITY_DECIMAL_STORE_ID_STORE_STORE_ID" table="catalog_category_entity_decimal" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_CATEGORY_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_CATEGORY_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_CATEGORY_ENTITY_DECIMAL_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_DECIMAL_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_DECIMAL_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_DECIMAL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -366,30 +366,30 @@ default="0"/> <column xsi:type="int" name="value" padding="11" unsigned="false" nullable="true" identity="false" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_INT_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_INT_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_category_entity_int" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_INT_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_INT_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_category_entity_int" column="entity_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_CATEGORY_ENTITY_INT_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_CATEGORY_ENTITY_INT_STORE_ID_STORE_STORE_ID" table="catalog_category_entity_int" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_CATEGORY_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_CATEGORY_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_CATEGORY_ENTITY_INT_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_INT_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_INT_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_INT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -404,30 +404,30 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0"/> <column xsi:type="text" name="value" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_TEXT_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_TEXT_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_category_entity_text" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_TEXT_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_TEXT_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_category_entity_text" column="entity_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_CATEGORY_ENTITY_TEXT_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_CATEGORY_ENTITY_TEXT_STORE_ID_STORE_STORE_ID" table="catalog_category_entity_text" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_CATEGORY_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_CATEGORY_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_CATEGORY_ENTITY_TEXT_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_TEXT_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_TEXT_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_TEXT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -442,30 +442,30 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_category_entity_varchar" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_CTGR_ENTT_VCHR_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_ENTT_VCHR_ENTT_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_category_entity_varchar" column="entity_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_CATEGORY_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_CATEGORY_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID" table="catalog_category_entity_varchar" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_CATEGORY_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_CATEGORY_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_CATEGORY_ENTITY_VARCHAR_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_VARCHAR_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_CATEGORY_ENTITY_VARCHAR_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_ENTITY_VARCHAR_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -479,22 +479,22 @@ default="0" comment="Product ID"/> <column xsi:type="int" name="position" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Position"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="category_id"/> <column name="product_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_CTGR_PRD_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_category_product" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_PRD_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_category_product" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_CTGR_PRD_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_CTGR_PRD_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_category_product" column="category_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_CATEGORY_PRODUCT_CATEGORY_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_CATEGORY_PRODUCT_CATEGORY_ID_PRODUCT_ID"> <column name="category_id"/> <column name="product_id"/> </constraint> - <index name="CATALOG_CATEGORY_PRODUCT_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_CATEGORY_PRODUCT_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -512,18 +512,18 @@ default="0" comment="Store ID"/> <column xsi:type="smallint" name="visibility" padding="5" unsigned="true" nullable="false" identity="false" comment="Visibility"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="category_id"/> <column name="product_id"/> <column name="store_id"/> </constraint> - <index name="CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY" indexType="btree"> + <index referenceId="CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY" indexType="btree"> <column name="product_id"/> <column name="store_id"/> <column name="category_id"/> <column name="visibility"/> </index> - <index name="CAT_CTGR_PRD_IDX_STORE_ID_CTGR_ID_VISIBILITY_IS_PARENT_POSITION" indexType="btree"> + <index referenceId="CAT_CTGR_PRD_IDX_STORE_ID_CTGR_ID_VISIBILITY_IS_PARENT_POSITION" indexType="btree"> <column name="store_id"/> <column name="category_id"/> <column name="visibility"/> @@ -542,29 +542,29 @@ default="0" comment="Product ID"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="true" identity="false" comment="Store ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="catalog_compare_item_id"/> </constraint> - <constraint xsi:type="foreign" name="CATALOG_COMPARE_ITEM_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_COMPARE_ITEM_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="catalog_compare_item" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_COMPARE_ITEM_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_COMPARE_ITEM_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="catalog_compare_item" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_COMPARE_ITEM_STORE_ID_STORE_STORE_ID" table="catalog_compare_item" + <constraint xsi:type="foreign" referenceId="CATALOG_COMPARE_ITEM_STORE_ID_STORE_STORE_ID" table="catalog_compare_item" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="CATALOG_COMPARE_ITEM_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_COMPARE_ITEM_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> - <index name="CATALOG_COMPARE_ITEM_VISITOR_ID_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_COMPARE_ITEM_VISITOR_ID_PRODUCT_ID" indexType="btree"> <column name="visitor_id"/> <column name="product_id"/> </index> - <index name="CATALOG_COMPARE_ITEM_CUSTOMER_ID_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_COMPARE_ITEM_CUSTOMER_ID_PRODUCT_ID" indexType="btree"> <column name="customer_id"/> <column name="product_id"/> </index> - <index name="CATALOG_COMPARE_ITEM_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_COMPARE_ITEM_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -574,17 +574,17 @@ comment="Product ID"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Website ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_id"/> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_WEBSITE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_WEBSITE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="catalog_product_website" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_WS_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_website" + <constraint xsi:type="foreign" referenceId="CAT_PRD_WS_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_website" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_WEBSITE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_WEBSITE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -593,7 +593,7 @@ <column xsi:type="smallint" name="link_type_id" padding="5" unsigned="true" nullable="false" identity="true" comment="Link Type ID"/> <column xsi:type="varchar" name="code" nullable="true" length="32" comment="Code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="link_type_id"/> </constraint> </table> @@ -607,27 +607,27 @@ default="0" comment="Linked Product ID"/> <column xsi:type="smallint" name="link_type_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Link Type ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="link_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_LNK_LNKED_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_link" + <constraint xsi:type="foreign" referenceId="CAT_PRD_LNK_LNKED_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_link" column="linked_product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_LINK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_LINK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="catalog_product_link" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_LNK_LNK_TYPE_ID_CAT_PRD_LNK_TYPE_LNK_TYPE_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_LNK_LNK_TYPE_ID_CAT_PRD_LNK_TYPE_LNK_TYPE_ID" table="catalog_product_link" column="link_type_id" referenceTable="catalog_product_link_type" referenceColumn="link_type_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_LINK_LINK_TYPE_ID_PRODUCT_ID_LINKED_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_LINK_LINK_TYPE_ID_PRODUCT_ID_LINKED_PRODUCT_ID"> <column name="link_type_id"/> <column name="product_id"/> <column name="linked_product_id"/> </constraint> - <index name="CATALOG_PRODUCT_LINK_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_LINK_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> - <index name="CATALOG_PRODUCT_LINK_LINKED_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_LINK_LINKED_PRODUCT_ID" indexType="btree"> <column name="linked_product_id"/> </index> </table> @@ -640,13 +640,13 @@ <column xsi:type="varchar" name="product_link_attribute_code" nullable="true" length="32" comment="Product Link Attribute Code"/> <column xsi:type="varchar" name="data_type" nullable="true" length="32" comment="Data Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_link_attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_LNK_ATTR_LNK_TYPE_ID_CAT_PRD_LNK_TYPE_LNK_TYPE_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_LNK_ATTR_LNK_TYPE_ID_CAT_PRD_LNK_TYPE_LNK_TYPE_ID" table="catalog_product_link_attribute" column="link_type_id" referenceTable="catalog_product_link_type" referenceColumn="link_type_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_LINK_ATTRIBUTE_LINK_TYPE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_LINK_ATTRIBUTE_LINK_TYPE_ID" indexType="btree"> <column name="link_type_id"/> </index> </table> @@ -660,21 +660,21 @@ comment="Link ID"/> <column xsi:type="decimal" name="value" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_LNK_ATTR_DEC_LNK_ID_CAT_PRD_LNK_LNK_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_LNK_ATTR_DEC_LNK_ID_CAT_PRD_LNK_LNK_ID" table="catalog_product_link_attribute_decimal" column="link_id" referenceTable="catalog_product_link" referenceColumn="link_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_AB2EFA9A14F7BCF1D5400056203D14B6" + <constraint xsi:type="foreign" referenceId="FK_AB2EFA9A14F7BCF1D5400056203D14B6" table="catalog_product_link_attribute_decimal" column="product_link_attribute_id" referenceTable="catalog_product_link_attribute" referenceColumn="product_link_attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_LNK_ATTR_DEC_PRD_LNK_ATTR_ID_LNK_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_LNK_ATTR_DEC_PRD_LNK_ATTR_ID_LNK_ID"> <column name="product_link_attribute_id"/> <column name="link_id"/> </constraint> - <index name="CATALOG_PRODUCT_LINK_ATTRIBUTE_DECIMAL_LINK_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_LINK_ATTRIBUTE_DECIMAL_LINK_ID" indexType="btree"> <column name="link_id"/> </index> </table> @@ -688,21 +688,21 @@ comment="Link ID"/> <column xsi:type="int" name="value" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_LNK_ATTR_INT_LNK_ID_CAT_PRD_LNK_LNK_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_LNK_ATTR_INT_LNK_ID_CAT_PRD_LNK_LNK_ID" table="catalog_product_link_attribute_int" column="link_id" referenceTable="catalog_product_link" referenceColumn="link_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_D6D878F8BA2A4282F8DDED7E6E3DE35C" + <constraint xsi:type="foreign" referenceId="FK_D6D878F8BA2A4282F8DDED7E6E3DE35C" table="catalog_product_link_attribute_int" column="product_link_attribute_id" referenceTable="catalog_product_link_attribute" referenceColumn="product_link_attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_LNK_ATTR_INT_PRD_LNK_ATTR_ID_LNK_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_LNK_ATTR_INT_PRD_LNK_ATTR_ID_LNK_ID"> <column name="product_link_attribute_id"/> <column name="link_id"/> </constraint> - <index name="CATALOG_PRODUCT_LINK_ATTRIBUTE_INT_LINK_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_LINK_ATTRIBUTE_INT_LINK_ID" indexType="btree"> <column name="link_id"/> </index> </table> @@ -715,21 +715,21 @@ <column xsi:type="int" name="link_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Link ID"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_LNK_ATTR_VCHR_LNK_ID_CAT_PRD_LNK_LNK_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_LNK_ATTR_VCHR_LNK_ID_CAT_PRD_LNK_LNK_ID" table="catalog_product_link_attribute_varchar" column="link_id" referenceTable="catalog_product_link" referenceColumn="link_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_DEE9C4DA61CFCC01DFCF50F0D79CEA51" + <constraint xsi:type="foreign" referenceId="FK_DEE9C4DA61CFCC01DFCF50F0D79CEA51" table="catalog_product_link_attribute_varchar" column="product_link_attribute_id" referenceTable="catalog_product_link_attribute" referenceColumn="product_link_attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_LNK_ATTR_VCHR_PRD_LNK_ATTR_ID_LNK_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_LNK_ATTR_VCHR_PRD_LNK_ATTR_ID_LNK_ID"> <column name="product_link_attribute_id"/> <column name="link_id"/> </constraint> - <index name="CATALOG_PRODUCT_LINK_ATTRIBUTE_VARCHAR_LINK_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_LINK_ATTRIBUTE_VARCHAR_LINK_ID" indexType="btree"> <column name="link_id"/> </index> </table> @@ -751,29 +751,29 @@ comment="Website ID"/> <column xsi:type="decimal" name="percentage_value" scale="2" precision="5" unsigned="false" nullable="true" comment="Percentage value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_TIER_PRICE_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_TIER_PRICE_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" table="catalog_product_entity_tier_price" column="customer_group_id" referenceTable="customer_group" referenceColumn="customer_group_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_TIER_PRICE_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_TIER_PRICE_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_tier_price" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_TIER_PRICE_WS_ID_STORE_WS_WS_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_TIER_PRICE_WS_ID_STORE_WS_WS_ID" table="catalog_product_entity_tier_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="UNQ_E8AB433B9ACB00343ABB312AD2FAB087"> + <constraint xsi:type="unique" referenceId="UNQ_E8AB433B9ACB00343ABB312AD2FAB087"> <column name="entity_id"/> <column name="all_groups"/> <column name="customer_group_id"/> <column name="qty"/> <column name="website_id"/> </constraint> - <index name="CATALOG_PRODUCT_ENTITY_TIER_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_TIER_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_TIER_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_TIER_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -788,13 +788,13 @@ comment="Media entry type"/> <column xsi:type="smallint" name="disabled" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Visibility status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_MDA_GLR_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_MDA_GLR_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_media_gallery" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -813,26 +813,26 @@ default="0" comment="Is Disabled"/> <column xsi:type="int" name="record_id" padding="10" unsigned="true" nullable="false" identity="true" comment="Record Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="record_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_MDA_GLR_VAL_VAL_ID_CAT_PRD_ENTT_MDA_GLR_VAL_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_VAL_ID_CAT_PRD_ENTT_MDA_GLR_VAL_ID" table="catalog_product_entity_media_gallery_value" column="value_id" referenceTable="catalog_product_entity_media_gallery" referenceColumn="value_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_MDA_GLR_VAL_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_media_gallery_value" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_MDA_GLR_VAL_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_media_gallery_value" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID" indexType="btree"> <column name="value_id"/> </index> </table> @@ -854,13 +854,13 @@ comment="Image Size Y"/> <column xsi:type="int" name="sort_order" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_OPT_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_option" + <constraint xsi:type="foreign" referenceId="CAT_PRD_OPT_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_option" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_OPTION_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_OPTION_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -875,20 +875,20 @@ <column xsi:type="decimal" name="price" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Price"/> <column xsi:type="varchar" name="price_type" nullable="false" length="7" default="fixed" comment="Price Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_price_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_OPT_PRICE_OPT_ID_CAT_PRD_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_OPT_PRICE_OPT_ID_CAT_PRD_OPT_OPT_ID" table="catalog_product_option_price" column="option_id" referenceTable="catalog_product_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_OPTION_PRICE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_OPTION_PRICE_STORE_ID_STORE_STORE_ID" table="catalog_product_option_price" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_OPTION_PRICE_OPTION_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_OPTION_PRICE_OPTION_ID_STORE_ID"> <column name="option_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_OPTION_PRICE_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_OPTION_PRICE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -901,20 +901,20 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store ID"/> <column xsi:type="varchar" name="title" nullable="true" length="255" comment="Title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_title_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_OPT_TTL_OPT_ID_CAT_PRD_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_OPT_TTL_OPT_ID_CAT_PRD_OPT_OPT_ID" table="catalog_product_option_title" column="option_id" referenceTable="catalog_product_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_OPTION_TITLE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_OPTION_TITLE_STORE_ID_STORE_STORE_ID" table="catalog_product_option_title" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_OPTION_TITLE_OPTION_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_OPTION_TITLE_OPTION_ID_STORE_ID"> <column name="option_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_OPTION_TITLE_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_OPTION_TITLE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -927,13 +927,13 @@ <column xsi:type="varchar" name="sku" nullable="true" length="64" comment="SKU"/> <column xsi:type="int" name="sort_order" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_type_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_OPT_TYPE_VAL_OPT_ID_CAT_PRD_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_OPT_TYPE_VAL_OPT_ID_CAT_PRD_OPT_OPT_ID" table="catalog_product_option_type_value" column="option_id" referenceTable="catalog_product_option" referenceColumn="option_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_OPTION_TYPE_VALUE_OPTION_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_OPTION_TYPE_VALUE_OPTION_ID" indexType="btree"> <column name="option_id"/> </index> </table> @@ -948,21 +948,21 @@ <column xsi:type="decimal" name="price" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Price"/> <column xsi:type="varchar" name="price_type" nullable="false" length="7" default="fixed" comment="Price Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_type_price_id"/> </constraint> - <constraint xsi:type="foreign" name="FK_B523E3378E8602F376CC415825576B7F" + <constraint xsi:type="foreign" referenceId="FK_B523E3378E8602F376CC415825576B7F" table="catalog_product_option_type_price" column="option_type_id" referenceTable="catalog_product_option_type_value" referenceColumn="option_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_OPTION_TYPE_PRICE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_OPTION_TYPE_PRICE_STORE_ID_STORE_STORE_ID" table="catalog_product_option_type_price" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_OPTION_TYPE_PRICE_OPTION_TYPE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_OPTION_TYPE_PRICE_OPTION_TYPE_ID_STORE_ID"> <column name="option_type_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_OPTION_TYPE_PRICE_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_OPTION_TYPE_PRICE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -975,21 +975,21 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store ID"/> <column xsi:type="varchar" name="title" nullable="true" length="255" comment="Title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_type_title_id"/> </constraint> - <constraint xsi:type="foreign" name="FK_C085B9CF2C2A302E8043FDEA1937D6A2" + <constraint xsi:type="foreign" referenceId="FK_C085B9CF2C2A302E8043FDEA1937D6A2" table="catalog_product_option_type_title" column="option_type_id" referenceTable="catalog_product_option_type_value" referenceColumn="option_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_OPTION_TYPE_TITLE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_OPTION_TYPE_TITLE_STORE_ID_STORE_STORE_ID" table="catalog_product_option_type_title" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_OPTION_TYPE_TITLE_OPTION_TYPE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_OPTION_TYPE_TITLE_OPTION_TYPE_ID_STORE_ID"> <column name="option_type_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_OPTION_TYPE_TITLE_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_OPTION_TYPE_TITLE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1037,16 +1037,16 @@ identity="false" default="0" comment="Is Visible in Grid"/> <column xsi:type="smallint" name="is_filterable_in_grid" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Is Filterable in Grid"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="CATALOG_EAV_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_EAV_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="catalog_eav_attribute" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <index name="CATALOG_EAV_ATTRIBUTE_USED_FOR_SORT_BY" indexType="btree"> + <index referenceId="CATALOG_EAV_ATTRIBUTE_USED_FOR_SORT_BY" indexType="btree"> <column name="used_for_sort_by"/> </index> - <index name="CATALOG_EAV_ATTRIBUTE_USED_IN_PRODUCT_LISTING" indexType="btree"> + <index referenceId="CATALOG_EAV_ATTRIBUTE_USED_IN_PRODUCT_LISTING" indexType="btree"> <column name="used_in_product_listing"/> </index> </table> @@ -1055,17 +1055,17 @@ comment="Parent ID"/> <column xsi:type="int" name="child_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Child ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="parent_id"/> <column name="child_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_RELATION_CHILD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_RELATION_CHILD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_relation" column="child_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_RELATION_PARENT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_RELATION_PARENT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_relation" column="parent_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_RELATION_CHILD_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_RELATION_CHILD_ID" indexType="btree"> <column name="child_id"/> </index> </table> @@ -1081,20 +1081,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="CAT_PRD_IDX_EAV_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> + <constraint xsi:type="primary" referenceId="CAT_PRD_IDX_EAV_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_VALUE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1110,20 +1110,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="CAT_PRD_IDX_EAV_DEC_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> + <constraint xsi:type="primary" referenceId="CAT_PRD_IDX_EAV_DEC_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_VALUE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1147,18 +1147,18 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_PRICE_MIN_PRICE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_MIN_PRICE" indexType="btree"> <column name="min_price"/> </index> - <index name="CAT_PRD_IDX_PRICE_WS_ID_CSTR_GROUP_ID_MIN_PRICE" indexType="btree"> + <index referenceId="CAT_PRD_IDX_PRICE_WS_ID_CSTR_GROUP_ID_MIN_PRICE" indexType="btree"> <column name="website_id"/> <column name="customer_group_id"/> <column name="min_price"/> @@ -1174,24 +1174,24 @@ comment="Website ID"/> <column xsi:type="decimal" name="min_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Min Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_IDX_TIER_PRICE_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_IDX_TIER_PRICE_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" table="catalog_product_index_tier_price" column="customer_group_id" referenceTable="customer_group" referenceColumn="customer_group_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_IDX_TIER_PRICE_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_IDX_TIER_PRICE_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_index_tier_price" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_IDX_TIER_PRICE_WS_ID_STORE_WS_WS_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_IDX_TIER_PRICE_WS_ID_STORE_WS_WS_ID" table="catalog_product_index_tier_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_INDEX_TIER_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_TIER_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_TIER_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_TIER_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -1203,12 +1203,12 @@ comment="Default store id for website"/> <column xsi:type="date" name="website_date" comment="Website Date"/> <column xsi:type="float" name="rate" unsigned="false" nullable="true" default="1" comment="Rate"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_IDX_WS_WS_ID_STORE_WS_WS_ID" table="catalog_product_index_website" + <constraint xsi:type="foreign" referenceId="CAT_PRD_IDX_WS_WS_ID_STORE_WS_WS_ID" table="catalog_product_index_website" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="CATALOG_PRODUCT_INDEX_WEBSITE_WEBSITE_DATE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_WEBSITE_WEBSITE_DATE" indexType="btree"> <column name="website_date"/> </index> </table> @@ -1226,7 +1226,7 @@ comment="Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="parent_id"/> <column name="child_id"/> <column name="customer_group_id"/> @@ -1247,7 +1247,7 @@ comment="Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="parent_id"/> <column name="child_id"/> <column name="customer_group_id"/> @@ -1268,7 +1268,7 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1288,7 +1288,7 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1316,7 +1316,7 @@ comment="Tier Price"/> <column xsi:type="decimal" name="base_tier" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Tier"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1344,7 +1344,7 @@ comment="Tier Price"/> <column xsi:type="decimal" name="base_tier" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Tier"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1364,7 +1364,7 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1384,7 +1384,7 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1406,7 +1406,7 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1429,7 +1429,7 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -1448,20 +1448,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="CAT_PRD_IDX_EAV_IDX_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> + <constraint xsi:type="primary" referenceId="CAT_PRD_IDX_EAV_IDX_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_IDX_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_IDX_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_IDX_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_IDX_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_IDX_VALUE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_IDX_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1477,20 +1477,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="CAT_PRD_IDX_EAV_TMP_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> + <constraint xsi:type="primary" referenceId="CAT_PRD_IDX_EAV_TMP_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_TMP_ATTRIBUTE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_ATTRIBUTE_ID" indexType="hash"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_TMP_STORE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_STORE_ID" indexType="hash"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_TMP_VALUE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_VALUE" indexType="hash"> <column name="value"/> </index> </table> @@ -1506,20 +1506,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="CAT_PRD_IDX_EAV_DEC_IDX_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> + <constraint xsi:type="primary" referenceId="CAT_PRD_IDX_EAV_DEC_IDX_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_IDX_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_IDX_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_IDX_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_IDX_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_IDX_VALUE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_IDX_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1535,20 +1535,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="CAT_PRD_IDX_EAV_DEC_TMP_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> + <constraint xsi:type="primary" referenceId="CAT_PRD_IDX_EAV_DEC_TMP_ENTT_ID_ATTR_ID_STORE_ID_VAL_SOURCE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_ATTRIBUTE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_ATTRIBUTE_ID" indexType="hash"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_STORE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_STORE_ID" indexType="hash"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_VALUE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_VALUE" indexType="hash"> <column name="value"/> </index> </table> @@ -1572,18 +1572,18 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_PRICE_IDX_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_IDX_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_PRICE_IDX_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_IDX_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_PRICE_IDX_MIN_PRICE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_IDX_MIN_PRICE" indexType="btree"> <column name="min_price"/> </index> </table> @@ -1607,18 +1607,18 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_PRICE_TMP_CUSTOMER_GROUP_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_CUSTOMER_GROUP_ID" indexType="hash"> <column name="customer_group_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_PRICE_TMP_WEBSITE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_WEBSITE_ID" indexType="hash"> <column name="website_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_PRICE_TMP_MIN_PRICE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_MIN_PRICE" indexType="hash"> <column name="min_price"/> </index> </table> @@ -1636,12 +1636,12 @@ default="0" comment="Store ID"/> <column xsi:type="smallint" name="visibility" padding="5" unsigned="true" nullable="false" identity="false" comment="Visibility"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="category_id"/> <column name="product_id"/> <column name="store_id"/> </constraint> - <index name="CAT_CTGR_PRD_IDX_TMP_PRD_ID_CTGR_ID_STORE_ID" indexType="hash"> + <index referenceId="CAT_CTGR_PRD_IDX_TMP_PRD_ID_CTGR_ID_STORE_ID" indexType="hash"> <column name="product_id"/> <column name="category_id"/> <column name="store_id"/> @@ -1652,14 +1652,14 @@ <column xsi:type="int" name="value_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Value media Entry ID"/> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false"/> - <constraint xsi:type="foreign" name="FK_A6C6C8FAA386736921D3A7C4B50B1185" + <constraint xsi:type="foreign" referenceId="FK_A6C6C8FAA386736921D3A7C4B50B1185" table="catalog_product_entity_media_gallery_value_to_entity" column="value_id" referenceTable="catalog_product_entity_media_gallery" referenceColumn="value_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_MDA_GLR_VAL_TO_ENTT_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_TO_ENTT_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_media_gallery_value_to_entity" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_ENTT_MDA_GLR_VAL_TO_ENTT_VAL_ID_ENTT_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_TO_ENTT_VAL_ID_ENTT_ID"> <column name="value_id"/> <column name="entity_id"/> </constraint> @@ -1676,20 +1676,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_VALUE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1705,20 +1705,20 @@ comment="Value"/> <column xsi:type="int" name="source_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Original entity Id for attribute value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> <column name="value"/> <column name="source_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_VALUE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1742,18 +1742,18 @@ comment="Max Price"/> <column xsi:type="decimal" name="tier_price" scale="4" precision="12" unsigned="false" nullable="true" comment="Tier Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index name="CATALOG_PRODUCT_INDEX_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOG_PRODUCT_INDEX_PRICE_MIN_PRICE" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_MIN_PRICE" indexType="btree"> <column name="min_price"/> </index> - <index name="CAT_PRD_IDX_PRICE_WS_ID_CSTR_GROUP_ID_MIN_PRICE" indexType="btree"> + <index referenceId="CAT_PRD_IDX_PRICE_WS_ID_CSTR_GROUP_ID_MIN_PRICE" indexType="btree"> <column name="website_id"/> <column name="customer_group_id"/> <column name="min_price"/> @@ -1773,18 +1773,18 @@ default="0" comment="Store ID"/> <column xsi:type="smallint" name="visibility" padding="5" unsigned="true" nullable="false" identity="false" comment="Visibility"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="category_id"/> <column name="product_id"/> <column name="store_id"/> </constraint> - <index name="CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY" indexType="btree"> + <index referenceId="CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY" indexType="btree"> <column name="product_id"/> <column name="store_id"/> <column name="category_id"/> <column name="visibility"/> </index> - <index name="CAT_CTGR_PRD_IDX_STORE_ID_CTGR_ID_VISIBILITY_IS_PARENT_POSITION" indexType="btree"> + <index referenceId="CAT_CTGR_PRD_IDX_STORE_ID_CTGR_ID_VISIBILITY_IS_PARENT_POSITION" indexType="btree"> <column name="store_id"/> <column name="category_id"/> <column name="visibility"/> @@ -1805,21 +1805,21 @@ comment="Product Id"/> <column xsi:type="bigint" name="added_at" padding="20" unsigned="false" nullable="false" identity="false" comment="Added At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="action_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_FRONTEND_ACTION_CSTR_ID_CSTR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_FRONTEND_ACTION_CSTR_ID_CSTR_ENTT_ENTT_ID" table="catalog_product_frontend_action" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_FRONTEND_ACTION_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_FRONTEND_ACTION_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_frontend_action" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE" /> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_FRONTEND_ACTION_VISITOR_ID_PRODUCT_ID_TYPE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_FRONTEND_ACTION_VISITOR_ID_PRODUCT_ID_TYPE_ID"> <column name="visitor_id"/> <column name="product_id"/> <column name="type_id"/> </constraint> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_FRONTEND_ACTION_CUSTOMER_ID_PRODUCT_ID_TYPE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_FRONTEND_ACTION_CUSTOMER_ID_PRODUCT_ID_TYPE_ID"> <column name="customer_id"/> <column name="product_id"/> <column name="type_id"/> diff --git a/app/code/Magento/CatalogInventory/etc/db_schema.xml b/app/code/Magento/CatalogInventory/etc/db_schema.xml index 8a6ae8d2d93c6..5ac7fedc5aa18 100644 --- a/app/code/Magento/CatalogInventory/etc/db_schema.xml +++ b/app/code/Magento/CatalogInventory/etc/db_schema.xml @@ -13,10 +13,10 @@ <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Website Id"/> <column xsi:type="varchar" name="stock_name" nullable="true" length="255" comment="Stock Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="stock_id"/> </constraint> - <index name="CATALOGINVENTORY_STOCK_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -71,23 +71,23 @@ identity="false" default="0" comment="Is Divided into Multiple Boxes for Shipping"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="item_id"/> </constraint> - <constraint xsi:type="foreign" name="CATINV_STOCK_ITEM_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CATINV_STOCK_ITEM_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="cataloginventory_stock_item" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATINV_STOCK_ITEM_STOCK_ID_CATINV_STOCK_STOCK_ID" + <constraint xsi:type="foreign" referenceId="CATINV_STOCK_ITEM_STOCK_ID_CATINV_STOCK_STOCK_ID" table="cataloginventory_stock_item" column="stock_id" referenceTable="cataloginventory_stock" referenceColumn="stock_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOGINVENTORY_STOCK_ITEM_PRODUCT_ID_STOCK_ID"> + <constraint xsi:type="unique" referenceId="CATALOGINVENTORY_STOCK_ITEM_PRODUCT_ID_STOCK_ID"> <column name="product_id"/> <column name="stock_id"/> </constraint> - <index name="CATALOGINVENTORY_STOCK_ITEM_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_ITEM_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_ITEM_STOCK_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_ITEM_STOCK_ID" indexType="btree"> <column name="stock_id"/> </index> </table> @@ -103,18 +103,18 @@ comment="Qty"/> <column xsi:type="smallint" name="stock_status" padding="5" unsigned="true" nullable="false" identity="false" comment="Stock Status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_id"/> <column name="website_id"/> <column name="stock_id"/> </constraint> - <index name="CATALOGINVENTORY_STOCK_STATUS_STOCK_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_STOCK_ID" indexType="btree"> <column name="stock_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_STATUS_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_STATUS_STOCK_STATUS" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_STOCK_STATUS" indexType="btree"> <column name="stock_status"/> </index> </table> @@ -130,15 +130,15 @@ comment="Qty"/> <column xsi:type="smallint" name="stock_status" padding="5" unsigned="true" nullable="false" identity="false" comment="Stock Status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_id"/> <column name="website_id"/> <column name="stock_id"/> </constraint> - <index name="CATALOGINVENTORY_STOCK_STATUS_IDX_STOCK_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_IDX_STOCK_ID" indexType="btree"> <column name="stock_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_STATUS_IDX_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_IDX_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -154,15 +154,15 @@ comment="Qty"/> <column xsi:type="smallint" name="stock_status" padding="5" unsigned="true" nullable="false" identity="false" comment="Stock Status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_id"/> <column name="website_id"/> <column name="stock_id"/> </constraint> - <index name="CATALOGINVENTORY_STOCK_STATUS_TMP_STOCK_ID" indexType="hash"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_STOCK_ID" indexType="hash"> <column name="stock_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_STATUS_TMP_WEBSITE_ID" indexType="hash"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_WEBSITE_ID" indexType="hash"> <column name="website_id"/> </index> </table> @@ -178,18 +178,18 @@ comment="Qty"/> <column xsi:type="smallint" name="stock_status" padding="5" unsigned="true" nullable="false" identity="false" comment="Stock Status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_id"/> <column name="website_id"/> <column name="stock_id"/> </constraint> - <index name="CATALOGINVENTORY_STOCK_STATUS_STOCK_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_STOCK_ID" indexType="btree"> <column name="stock_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_STATUS_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGINVENTORY_STOCK_STATUS_STOCK_STATUS" indexType="btree"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_STOCK_STATUS" indexType="btree"> <column name="stock_status"/> </index> </table> diff --git a/app/code/Magento/CatalogRule/etc/db_schema.xml b/app/code/Magento/CatalogRule/etc/db_schema.xml index f4c40a6930cc0..0ad71089bed5f 100644 --- a/app/code/Magento/CatalogRule/etc/db_schema.xml +++ b/app/code/Magento/CatalogRule/etc/db_schema.xml @@ -25,10 +25,10 @@ <column xsi:type="varchar" name="simple_action" nullable="true" length="32" comment="Simple Action"/> <column xsi:type="decimal" name="discount_amount" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Discount Amount"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> </constraint> - <index name="CATALOGRULE_IS_ACTIVE_SORT_ORDER_TO_DATE_FROM_DATE" indexType="btree"> + <index referenceId="CATALOGRULE_IS_ACTIVE_SORT_ORDER_TO_DATE_FROM_DATE" indexType="btree"> <column name="is_active"/> <column name="sort_order"/> <column name="to_date"/> @@ -57,10 +57,10 @@ default="0" comment="Sort Order"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Website Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_product_id"/> </constraint> - <constraint xsi:type="unique" name="UNQ_EAA51B56FF092A0DCB795D1CEF812B7B"> + <constraint xsi:type="unique" referenceId="UNQ_EAA51B56FF092A0DCB795D1CEF812B7B"> <column name="rule_id"/> <column name="from_time"/> <column name="to_time"/> @@ -69,19 +69,19 @@ <column name="product_id"/> <column name="sort_order"/> </constraint> - <index name="CATALOGRULE_PRODUCT_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOGRULE_PRODUCT_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGRULE_PRODUCT_FROM_TIME" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_FROM_TIME" indexType="btree"> <column name="from_time"/> </index> - <index name="CATALOGRULE_PRODUCT_TO_TIME" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_TO_TIME" indexType="btree"> <column name="to_time"/> </index> - <index name="CATALOGRULE_PRODUCT_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -98,22 +98,22 @@ comment="Website Id"/> <column xsi:type="date" name="latest_start_date" comment="Latest StartDate"/> <column xsi:type="date" name="earliest_end_date" comment="Earliest EndDate"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_product_price_id"/> </constraint> - <constraint xsi:type="unique" name="CATRULE_PRD_PRICE_RULE_DATE_WS_ID_CSTR_GROUP_ID_PRD_ID"> + <constraint xsi:type="unique" referenceId="CATRULE_PRD_PRICE_RULE_DATE_WS_ID_CSTR_GROUP_ID_PRD_ID"> <column name="rule_date"/> <column name="website_id"/> <column name="customer_group_id"/> <column name="product_id"/> </constraint> - <index name="CATALOGRULE_PRODUCT_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOGRULE_PRODUCT_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGRULE_PRODUCT_PRICE_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRICE_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -124,15 +124,15 @@ default="0" comment="Customer Group Id"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index name="CATALOGRULE_GROUP_WEBSITE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_GROUP_WEBSITE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOGRULE_GROUP_WEBSITE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_GROUP_WEBSITE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -140,17 +140,17 @@ <column xsi:type="int" name="rule_id" padding="10" unsigned="true" nullable="false" identity="false"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Website Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="CATALOGRULE_WEBSITE_RULE_ID_CATALOGRULE_RULE_ID" + <constraint xsi:type="foreign" referenceId="CATALOGRULE_WEBSITE_RULE_ID_CATALOGRULE_RULE_ID" table="catalogrule_website" column="rule_id" referenceTable="catalogrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOGRULE_WEBSITE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="CATALOGRULE_WEBSITE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="catalogrule_website" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="CATALOGRULE_WEBSITE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_WEBSITE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -159,17 +159,17 @@ <column xsi:type="int" name="rule_id" padding="10" unsigned="true" nullable="false" identity="false"/> <column xsi:type="int" name="customer_group_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Customer Group Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="customer_group_id"/> </constraint> - <constraint xsi:type="foreign" name="CATALOGRULE_CUSTOMER_GROUP_RULE_ID_CATALOGRULE_RULE_ID" + <constraint xsi:type="foreign" referenceId="CATALOGRULE_CUSTOMER_GROUP_RULE_ID_CATALOGRULE_RULE_ID" table="catalogrule_customer_group" column="rule_id" referenceTable="catalogrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATRULE_CSTR_GROUP_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="CATRULE_CSTR_GROUP_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" table="catalogrule_customer_group" column="customer_group_id" referenceTable="customer_group" referenceColumn="customer_group_id" onDelete="CASCADE"/> - <index name="CATALOGRULE_CUSTOMER_GROUP_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_CUSTOMER_GROUP_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> </table> @@ -195,10 +195,10 @@ default="0" comment="Sort Order"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Website Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_product_id"/> </constraint> - <constraint xsi:type="unique" name="UNQ_EAA51B56FF092A0DCB795D1CEF812B7B"> + <constraint xsi:type="unique" referenceId="UNQ_EAA51B56FF092A0DCB795D1CEF812B7B"> <column name="rule_id"/> <column name="from_time"/> <column name="to_time"/> @@ -207,19 +207,19 @@ <column name="product_id"/> <column name="sort_order"/> </constraint> - <index name="CATALOGRULE_PRODUCT_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOGRULE_PRODUCT_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGRULE_PRODUCT_FROM_TIME" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_FROM_TIME" indexType="btree"> <column name="from_time"/> </index> - <index name="CATALOGRULE_PRODUCT_TO_TIME" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_TO_TIME" indexType="btree"> <column name="to_time"/> </index> - <index name="CATALOGRULE_PRODUCT_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -237,22 +237,22 @@ comment="Website Id"/> <column xsi:type="date" name="latest_start_date" comment="Latest StartDate"/> <column xsi:type="date" name="earliest_end_date" comment="Earliest EndDate"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_product_price_id"/> </constraint> - <constraint xsi:type="unique" name="CATRULE_PRD_PRICE_RULE_DATE_WS_ID_CSTR_GROUP_ID_PRD_ID"> + <constraint xsi:type="unique" referenceId="CATRULE_PRD_PRICE_RULE_DATE_WS_ID_CSTR_GROUP_ID_PRD_ID"> <column name="rule_date"/> <column name="website_id"/> <column name="customer_group_id"/> <column name="product_id"/> </constraint> - <index name="CATALOGRULE_PRODUCT_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRICE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOGRULE_PRODUCT_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CATALOGRULE_PRODUCT_PRICE_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOGRULE_PRODUCT_PRICE_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -264,15 +264,15 @@ default="0" comment="Customer Group Id"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index name="CATALOGRULE_GROUP_WEBSITE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="CATALOGRULE_GROUP_WEBSITE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="CATALOGRULE_GROUP_WEBSITE_WEBSITE_ID" indexType="btree"> + <index referenceId="CATALOGRULE_GROUP_WEBSITE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> diff --git a/app/code/Magento/CatalogUrlRewrite/etc/db_schema.xml b/app/code/Magento/CatalogUrlRewrite/etc/db_schema.xml index 174173fa2019f..c8da5b59cf5f5 100644 --- a/app/code/Magento/CatalogUrlRewrite/etc/db_schema.xml +++ b/app/code/Magento/CatalogUrlRewrite/etc/db_schema.xml @@ -15,16 +15,16 @@ comment="category_id"/> <column xsi:type="int" name="product_id" padding="10" unsigned="true" nullable="false" identity="false" comment="product_id"/> - <constraint xsi:type="foreign" name="CAT_URL_REWRITE_PRD_CTGR_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_URL_REWRITE_PRD_CTGR_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_url_rewrite_product_category" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_BB79E64705D7F17FE181F23144528FC8" + <constraint xsi:type="foreign" referenceId="FK_BB79E64705D7F17FE181F23144528FC8" table="catalog_url_rewrite_product_category" column="url_rewrite_id" referenceTable="url_rewrite" referenceColumn="url_rewrite_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_URL_REWRITE_PRD_CTGR_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_URL_REWRITE_PRD_CTGR_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID" table="catalog_url_rewrite_product_category" column="category_id" referenceTable="catalog_category_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CATALOG_URL_REWRITE_PRODUCT_CATEGORY_CATEGORY_ID_PRODUCT_ID" indexType="btree"> + <index referenceId="CATALOG_URL_REWRITE_PRODUCT_CATEGORY_CATEGORY_ID_PRODUCT_ID" indexType="btree"> <column name="category_id"/> <column name="product_id"/> </index> diff --git a/app/code/Magento/CheckoutAgreements/etc/db_schema.xml b/app/code/Magento/CheckoutAgreements/etc/db_schema.xml index 31b3111df98eb..09cd1c5b63965 100644 --- a/app/code/Magento/CheckoutAgreements/etc/db_schema.xml +++ b/app/code/Magento/CheckoutAgreements/etc/db_schema.xml @@ -20,7 +20,7 @@ default="0" comment="Is Html"/> <column xsi:type="smallint" name="mode" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Applied mode"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="agreement_id"/> </constraint> </table> @@ -29,14 +29,14 @@ comment="Agreement Id"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="agreement_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="CHKT_AGRT_STORE_AGRT_ID_CHKT_AGRT_AGRT_ID" table="checkout_agreement_store" + <constraint xsi:type="foreign" referenceId="CHKT_AGRT_STORE_AGRT_ID_CHKT_AGRT_AGRT_ID" table="checkout_agreement_store" column="agreement_id" referenceTable="checkout_agreement" referenceColumn="agreement_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CHECKOUT_AGREEMENT_STORE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CHECKOUT_AGREEMENT_STORE_STORE_ID_STORE_STORE_ID" table="checkout_agreement_store" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> </table> diff --git a/app/code/Magento/Cms/etc/db_schema.xml b/app/code/Magento/Cms/etc/db_schema.xml index 2b825544f56f1..3075601215fe3 100644 --- a/app/code/Magento/Cms/etc/db_schema.xml +++ b/app/code/Magento/Cms/etc/db_schema.xml @@ -19,10 +19,10 @@ comment="Block Modification Time"/> <column xsi:type="smallint" name="is_active" padding="6" unsigned="false" nullable="false" identity="false" default="1" comment="Is Block Active"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="block_id"/> </constraint> - <index name="CMS_BLOCK_TITLE_IDENTIFIER_CONTENT" indexType="fulltext"> + <index referenceId="CMS_BLOCK_TITLE_IDENTIFIER_CONTENT" indexType="fulltext"> <column name="title"/> <column name="identifier"/> <column name="content"/> @@ -32,15 +32,15 @@ <column xsi:type="smallint" name="block_id" padding="6" unsigned="false" nullable="false" identity="false"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="block_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="CMS_BLOCK_STORE_BLOCK_ID_CMS_BLOCK_BLOCK_ID" table="cms_block_store" + <constraint xsi:type="foreign" referenceId="CMS_BLOCK_STORE_BLOCK_ID_CMS_BLOCK_BLOCK_ID" table="cms_block_store" column="block_id" referenceTable="cms_block" referenceColumn="block_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CMS_BLOCK_STORE_STORE_ID_STORE_STORE_ID" table="cms_block_store" + <constraint xsi:type="foreign" referenceId="CMS_BLOCK_STORE_STORE_ID_STORE_STORE_ID" table="cms_block_store" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="CMS_BLOCK_STORE_STORE_ID" indexType="btree"> + <index referenceId="CMS_BLOCK_STORE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -71,13 +71,13 @@ <column xsi:type="date" name="custom_theme_from" comment="Page Custom Theme Active From Date"/> <column xsi:type="date" name="custom_theme_to" comment="Page Custom Theme Active To Date"/> <column xsi:type="varchar" name="meta_title" nullable="true" length="255" comment="Page Meta Title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id"/> </constraint> - <index name="CMS_PAGE_IDENTIFIER" indexType="btree"> + <index referenceId="CMS_PAGE_IDENTIFIER" indexType="btree"> <column name="identifier"/> </index> - <index name="CMS_PAGE_TITLE_META_KEYWORDS_META_DESCRIPTION_IDENTIFIER_CONTENT" indexType="fulltext"> + <index referenceId="CMS_PAGE_TITLE_META_KEYWORDS_META_DESCRIPTION_IDENTIFIER_CONTENT" indexType="fulltext"> <column name="title"/> <column name="meta_keywords"/> <column name="meta_description"/> @@ -89,15 +89,15 @@ <column xsi:type="smallint" name="page_id" padding="6" unsigned="false" nullable="false" identity="false"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="CMS_PAGE_STORE_PAGE_ID_CMS_PAGE_PAGE_ID" table="cms_page_store" + <constraint xsi:type="foreign" referenceId="CMS_PAGE_STORE_PAGE_ID_CMS_PAGE_PAGE_ID" table="cms_page_store" column="page_id" referenceTable="cms_page" referenceColumn="page_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CMS_PAGE_STORE_STORE_ID_STORE_STORE_ID" table="cms_page_store" + <constraint xsi:type="foreign" referenceId="CMS_PAGE_STORE_STORE_ID_STORE_STORE_ID" table="cms_page_store" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="CMS_PAGE_STORE_STORE_ID" indexType="btree"> + <index referenceId="CMS_PAGE_STORE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/Config/etc/db_schema.xml b/app/code/Magento/Config/etc/db_schema.xml index 3f55d582776ce..8aeac802fbd91 100644 --- a/app/code/Magento/Config/etc/db_schema.xml +++ b/app/code/Magento/Config/etc/db_schema.xml @@ -15,10 +15,10 @@ default="0" comment="Config Scope Id"/> <column xsi:type="varchar" name="path" nullable="false" length="255" default="general" comment="Config Path"/> <column xsi:type="text" name="value" nullable="true" comment="Config Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="config_id"/> </constraint> - <constraint xsi:type="unique" name="CORE_CONFIG_DATA_SCOPE_SCOPE_ID_PATH"> + <constraint xsi:type="unique" referenceId="CORE_CONFIG_DATA_SCOPE_SCOPE_ID_PATH"> <column name="scope"/> <column name="scope_id"/> <column name="path"/> diff --git a/app/code/Magento/ConfigurableProduct/etc/db_schema.xml b/app/code/Magento/ConfigurableProduct/etc/db_schema.xml index 7c6661a5f399a..d6917e8c1845a 100644 --- a/app/code/Magento/ConfigurableProduct/etc/db_schema.xml +++ b/app/code/Magento/ConfigurableProduct/etc/db_schema.xml @@ -17,13 +17,13 @@ default="0" comment="Attribute ID"/> <column xsi:type="smallint" name="position" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Position"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="product_super_attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_SPR_ATTR_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_SPR_ATTR_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_super_attribute" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_SUPER_ATTRIBUTE_PRODUCT_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_SUPER_ATTRIBUTE_PRODUCT_ID_ATTRIBUTE_ID"> <column name="product_id"/> <column name="attribute_id"/> </constraint> @@ -39,21 +39,21 @@ <column xsi:type="smallint" name="use_default" padding="5" unsigned="true" nullable="true" identity="false" default="0" comment="Use Default Value"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="FK_309442281DF7784210ED82B2CC51E5D5" + <constraint xsi:type="foreign" referenceId="FK_309442281DF7784210ED82B2CC51E5D5" table="catalog_product_super_attribute_label" column="product_super_attribute_id" referenceTable="catalog_product_super_attribute" referenceColumn="product_super_attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CATALOG_PRODUCT_SUPER_ATTRIBUTE_LABEL_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_SUPER_ATTRIBUTE_LABEL_STORE_ID_STORE_STORE_ID" table="catalog_product_super_attribute_label" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_SPR_ATTR_LBL_PRD_SPR_ATTR_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_SPR_ATTR_LBL_PRD_SPR_ATTR_ID_STORE_ID"> <column name="product_super_attribute_id"/> <column name="store_id"/> </constraint> - <index name="CATALOG_PRODUCT_SUPER_ATTRIBUTE_LABEL_STORE_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_SUPER_ATTRIBUTE_LABEL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -65,20 +65,20 @@ default="0" comment="Product ID"/> <column xsi:type="int" name="parent_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Parent ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="link_id"/> </constraint> - <constraint xsi:type="foreign" name="CAT_PRD_SPR_LNK_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_SPR_LNK_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_super_link" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_SPR_LNK_PARENT_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_SPR_LNK_PARENT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_super_link" column="parent_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CATALOG_PRODUCT_SUPER_LINK_PRODUCT_ID_PARENT_ID"> + <constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_SUPER_LINK_PRODUCT_ID_PARENT_ID"> <column name="product_id"/> <column name="parent_id"/> </constraint> - <index name="CATALOG_PRODUCT_SUPER_LINK_PARENT_ID" indexType="btree"> + <index referenceId="CATALOG_PRODUCT_SUPER_LINK_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> diff --git a/app/code/Magento/Cron/etc/db_schema.xml b/app/code/Magento/Cron/etc/db_schema.xml index deff05d3eec96..b3061eefa6313 100644 --- a/app/code/Magento/Cron/etc/db_schema.xml +++ b/app/code/Magento/Cron/etc/db_schema.xml @@ -18,13 +18,13 @@ <column xsi:type="timestamp" name="scheduled_at" on_update="false" nullable="true" comment="Scheduled At"/> <column xsi:type="timestamp" name="executed_at" on_update="false" nullable="true" comment="Executed At"/> <column xsi:type="timestamp" name="finished_at" on_update="false" nullable="true" comment="Finished At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="schedule_id"/> </constraint> - <index name="CRON_SCHEDULE_JOB_CODE" indexType="btree"> + <index referenceId="CRON_SCHEDULE_JOB_CODE" indexType="btree"> <column name="job_code"/> </index> - <index name="CRON_SCHEDULE_SCHEDULED_AT_STATUS" indexType="btree"> + <index referenceId="CRON_SCHEDULE_SCHEDULED_AT_STATUS" indexType="btree"> <column name="scheduled_at"/> <column name="status"/> </index> diff --git a/app/code/Magento/Customer/etc/db_schema.xml b/app/code/Magento/Customer/etc/db_schema.xml index 368ca417432fd..b3c15799011a2 100644 --- a/app/code/Magento/Customer/etc/db_schema.xml +++ b/app/code/Magento/Customer/etc/db_schema.xml @@ -50,28 +50,28 @@ <column xsi:type="timestamp" name="first_failure" on_update="false" nullable="true" comment="First Failure"/> <column xsi:type="timestamp" name="lock_expires" on_update="false" nullable="true" comment="Lock Expiration Date"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_STORE_ID_STORE_STORE_ID" table="customer_entity" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_STORE_ID_STORE_STORE_ID" table="customer_entity" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="customer_entity" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="CUSTOMER_ENTITY_EMAIL_WEBSITE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ENTITY_EMAIL_WEBSITE_ID"> <column name="email"/> <column name="website_id"/> </constraint> - <index name="CUSTOMER_ENTITY_STORE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="CUSTOMER_ENTITY_WEBSITE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="CUSTOMER_ENTITY_FIRSTNAME" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_FIRSTNAME" indexType="btree"> <column name="firstname"/> </index> - <index name="CUSTOMER_ENTITY_LASTNAME" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_LASTNAME" indexType="btree"> <column name="lastname"/> </index> </table> @@ -111,13 +111,13 @@ comment="VAT number validation request ID"/> <column xsi:type="int" name="vat_request_success" padding="10" unsigned="true" nullable="true" identity="false" comment="VAT number validation request success"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ADDRESS_ENTITY_PARENT_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ADDRESS_ENTITY_PARENT_ID_CUSTOMER_ENTITY_ENTITY_ID" table="customer_address_entity" column="parent_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="CUSTOMER_ADDRESS_ENTITY_PARENT_ID" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -130,23 +130,23 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" table="customer_address_entity_datetime" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_DTIME_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_DTIME_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" table="customer_address_entity_datetime" column="entity_id" referenceTable="customer_address_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ADDRESS_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ADDRESS_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ADDRESS_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ADDRESS_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -162,23 +162,23 @@ default="0" comment="Entity Id"/> <column xsi:type="decimal" name="value" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_DEC_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_DEC_ATTR_ID_EAV_ATTR_ATTR_ID" table="customer_address_entity_decimal" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_DEC_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_DEC_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" table="customer_address_entity_decimal" column="entity_id" referenceTable="customer_address_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ADDRESS_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ADDRESS_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ADDRESS_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ADDRESS_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -193,23 +193,23 @@ default="0" comment="Entity Id"/> <column xsi:type="int" name="value" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_INT_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_INT_ATTR_ID_EAV_ATTR_ATTR_ID" table="customer_address_entity_int" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_INT_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_INT_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" table="customer_address_entity_int" column="entity_id" referenceTable="customer_address_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ADDRESS_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ADDRESS_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ADDRESS_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ADDRESS_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -224,20 +224,20 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="text" name="value" nullable="false" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_TEXT_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_TEXT_ATTR_ID_EAV_ATTR_ATTR_ID" table="customer_address_entity_text" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_TEXT_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_TEXT_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" table="customer_address_entity_text" column="entity_id" referenceTable="customer_address_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ADDRESS_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ADDRESS_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ADDRESS_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -250,23 +250,23 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID" table="customer_address_entity_varchar" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CSTR_ADDR_ENTT_VCHR_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CSTR_ADDR_ENTT_VCHR_ENTT_ID_CSTR_ADDR_ENTT_ENTT_ID" table="customer_address_entity_varchar" column="entity_id" referenceTable="customer_address_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ADDRESS_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ADDRESS_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ADDRESS_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ADDRESS_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ADDRESS_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -280,23 +280,23 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_DATETIME_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_DATETIME_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_entity_datetime" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_DATETIME_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_DATETIME_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" table="customer_entity_datetime" column="entity_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -311,23 +311,23 @@ default="0" comment="Entity Id"/> <column xsi:type="decimal" name="value" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_DECIMAL_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_DECIMAL_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_entity_decimal" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_DECIMAL_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_DECIMAL_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" table="customer_entity_decimal" column="entity_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_DECIMAL_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -342,23 +342,23 @@ default="0" comment="Entity Id"/> <column xsi:type="int" name="value" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_INT_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_INT_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_entity_int" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_INT_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_INT_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" table="customer_entity_int" column="entity_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_INT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -372,20 +372,20 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="text" name="value" nullable="false" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_TEXT_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_TEXT_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_entity_text" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_TEXT_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_TEXT_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" table="customer_entity_text" column="entity_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -397,23 +397,23 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_VARCHAR_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_VARCHAR_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_entity_varchar" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_CUSTOMER_ENTITY_ENTITY_ID" table="customer_entity_varchar" column="entity_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID"> <column name="entity_id"/> <column name="attribute_id"/> </constraint> - <index name="CUSTOMER_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_VARCHAR_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="CUSTOMER_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="entity_id"/> <column name="attribute_id"/> <column name="value"/> @@ -425,7 +425,7 @@ comment="Customer Group Code"/> <column xsi:type="int" name="tax_class_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Tax Class Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="customer_group_id"/> </constraint> </table> @@ -451,10 +451,10 @@ identity="false" default="0" comment="Is Filterable in Grid"/> <column xsi:type="smallint" name="is_searchable_in_grid" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Is Searchable in Grid"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_EAV_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_EAV_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_eav_attribute" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> </table> @@ -462,14 +462,14 @@ <column xsi:type="varchar" name="form_code" nullable="false" length="32" comment="Form Code"/> <column xsi:type="smallint" name="attribute_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Attribute Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="form_code"/> <column name="attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="CUSTOMER_FORM_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="CUSTOMER_FORM_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="customer_form_attribute" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <index name="CUSTOMER_FORM_ATTRIBUTE_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="CUSTOMER_FORM_ATTRIBUTE_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -486,17 +486,17 @@ <column xsi:type="text" name="default_value" nullable="true" comment="Default Value"/> <column xsi:type="smallint" name="multiline_count" padding="5" unsigned="true" nullable="true" identity="false" comment="Multiline Count"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_id"/> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_EAV_ATTR_WS_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="CSTR_EAV_ATTR_WS_ATTR_ID_EAV_ATTR_ATTR_ID" table="customer_eav_attribute_website" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CSTR_EAV_ATTR_WS_WS_ID_STORE_WS_WS_ID" + <constraint xsi:type="foreign" referenceId="CSTR_EAV_ATTR_WS_WS_ID_STORE_WS_WS_ID" table="customer_eav_attribute_website" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="CUSTOMER_EAV_ATTRIBUTE_WEBSITE_WEBSITE_ID" indexType="btree"> + <index referenceId="CUSTOMER_EAV_ATTRIBUTE_WEBSITE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -508,13 +508,13 @@ <column xsi:type="varchar" name="session_id" nullable="true" length="64" comment="Session ID"/> <column xsi:type="timestamp" name="last_visit_at" on_update="true" nullable="true" default="CURRENT_TIMESTAMP" comment="Last Visit Time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="visitor_id"/> </constraint> - <index name="CUSTOMER_VISITOR_CUSTOMER_ID" indexType="btree"> + <index referenceId="CUSTOMER_VISITOR_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="CUSTOMER_VISITOR_LAST_VISIT_AT" indexType="btree"> + <index referenceId="CUSTOMER_VISITOR_LAST_VISIT_AT" indexType="btree"> <column name="last_visit_at"/> </index> </table> @@ -526,10 +526,10 @@ <column xsi:type="timestamp" name="last_login_at" on_update="false" nullable="true" comment="Last Login Time"/> <column xsi:type="timestamp" name="last_logout_at" on_update="false" nullable="true" comment="Last Logout Time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="log_id"/> </constraint> - <constraint xsi:type="unique" name="CUSTOMER_LOG_CUSTOMER_ID"> + <constraint xsi:type="unique" referenceId="CUSTOMER_LOG_CUSTOMER_ID"> <column name="customer_id"/> </constraint> </table> diff --git a/app/code/Magento/Directory/etc/db_schema.xml b/app/code/Magento/Directory/etc/db_schema.xml index 72fd929b98a07..c11e0ee525e37 100644 --- a/app/code/Magento/Directory/etc/db_schema.xml +++ b/app/code/Magento/Directory/etc/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="varchar" name="country_id" nullable="false" length="2" comment="Country Id in ISO-2"/> <column xsi:type="varchar" name="iso2_code" nullable="true" length="2" comment="Country ISO-2 format"/> <column xsi:type="varchar" name="iso3_code" nullable="true" length="3" comment="Country ISO-3"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="country_id"/> </constraint> </table> @@ -21,10 +21,10 @@ <column xsi:type="varchar" name="country_id" nullable="true" length="2" comment="Country Id in ISO-2"/> <column xsi:type="varchar" name="type" nullable="true" length="30" comment="Country Format Type"/> <column xsi:type="text" name="format" nullable="false" comment="Country Format"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="country_format_id"/> </constraint> - <constraint xsi:type="unique" name="DIRECTORY_COUNTRY_FORMAT_COUNTRY_ID_TYPE"> + <constraint xsi:type="unique" referenceId="DIRECTORY_COUNTRY_FORMAT_COUNTRY_ID_TYPE"> <column name="country_id"/> <column name="type"/> </constraint> @@ -36,10 +36,10 @@ comment="Country Id in ISO-2"/> <column xsi:type="varchar" name="code" nullable="true" length="32" comment="Region code"/> <column xsi:type="varchar" name="default_name" nullable="true" length="255" comment="Region Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="region_id"/> </constraint> - <index name="DIRECTORY_COUNTRY_REGION_COUNTRY_ID" indexType="btree"> + <index referenceId="DIRECTORY_COUNTRY_REGION_COUNTRY_ID" indexType="btree"> <column name="country_id"/> </index> </table> @@ -49,14 +49,14 @@ <column xsi:type="int" name="region_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Region Id"/> <column xsi:type="varchar" name="name" nullable="true" length="255" comment="Region Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="locale"/> <column name="region_id"/> </constraint> - <constraint xsi:type="foreign" name="DIR_COUNTRY_REGION_NAME_REGION_ID_DIR_COUNTRY_REGION_REGION_ID" + <constraint xsi:type="foreign" referenceId="DIR_COUNTRY_REGION_NAME_REGION_ID_DIR_COUNTRY_REGION_REGION_ID" table="directory_country_region_name" column="region_id" referenceTable="directory_country_region" referenceColumn="region_id" onDelete="CASCADE"/> - <index name="DIRECTORY_COUNTRY_REGION_NAME_REGION_ID" indexType="btree"> + <index referenceId="DIRECTORY_COUNTRY_REGION_NAME_REGION_ID" indexType="btree"> <column name="region_id"/> </index> </table> @@ -66,11 +66,11 @@ <column xsi:type="varchar" name="currency_to" nullable="false" length="3" comment="Currency Code Convert To"/> <column xsi:type="decimal" name="rate" scale="12" precision="24" unsigned="false" nullable="false" default="0" comment="Currency Conversion Rate"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="currency_from"/> <column name="currency_to"/> </constraint> - <index name="DIRECTORY_CURRENCY_RATE_CURRENCY_TO" indexType="btree"> + <index referenceId="DIRECTORY_CURRENCY_RATE_CURRENCY_TO" indexType="btree"> <column name="currency_to"/> </index> </table> diff --git a/app/code/Magento/Downloadable/etc/db_schema.xml b/app/code/Magento/Downloadable/etc/db_schema.xml index ed25628bcffd9..89d47644661a5 100644 --- a/app/code/Magento/Downloadable/etc/db_schema.xml +++ b/app/code/Magento/Downloadable/etc/db_schema.xml @@ -24,13 +24,13 @@ <column xsi:type="varchar" name="sample_url" nullable="true" length="255" comment="Sample Url"/> <column xsi:type="varchar" name="sample_file" nullable="true" length="255" comment="Sample File"/> <column xsi:type="varchar" name="sample_type" nullable="true" length="20" comment="Sample Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="link_id"/> </constraint> - <constraint xsi:type="foreign" name="DOWNLOADABLE_LINK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_LINK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="downloadable_link" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="DOWNLOADABLE_LINK_PRODUCT_ID_SORT_ORDER" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PRODUCT_ID_SORT_ORDER" indexType="btree"> <column name="product_id"/> <column name="sort_order"/> </index> @@ -44,19 +44,19 @@ default="0" comment="Website ID"/> <column xsi:type="decimal" name="price" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="price_id"/> </constraint> - <constraint xsi:type="foreign" name="DOWNLOADABLE_LINK_PRICE_LINK_ID_DOWNLOADABLE_LINK_LINK_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_LINK_PRICE_LINK_ID_DOWNLOADABLE_LINK_LINK_ID" table="downloadable_link_price" column="link_id" referenceTable="downloadable_link" referenceColumn="link_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="DOWNLOADABLE_LINK_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_LINK_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="downloadable_link_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="DOWNLOADABLE_LINK_PRICE_LINK_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PRICE_LINK_ID" indexType="btree"> <column name="link_id"/> </index> - <index name="DOWNLOADABLE_LINK_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -78,22 +78,22 @@ <column xsi:type="varchar" name="product_name" nullable="true" length="255" comment="Product name"/> <column xsi:type="varchar" name="product_sku" nullable="true" length="255" comment="Product sku"/> <column xsi:type="varchar" name="link_section_title" nullable="true" length="255" comment="Link_section_title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="purchased_id"/> </constraint> - <constraint xsi:type="foreign" name="DL_LNK_PURCHASED_CSTR_ID_CSTR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="DL_LNK_PURCHASED_CSTR_ID_CSTR_ENTT_ENTT_ID" table="downloadable_link_purchased" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="DOWNLOADABLE_LINK_PURCHASED_ORDER_ID_SALES_ORDER_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_LINK_PURCHASED_ORDER_ID_SALES_ORDER_ENTITY_ID" table="downloadable_link_purchased" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="SET NULL"/> - <index name="DOWNLOADABLE_LINK_PURCHASED_ORDER_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PURCHASED_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="DOWNLOADABLE_LINK_PURCHASED_ORDER_ITEM_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PURCHASED_ORDER_ITEM_ID" indexType="btree"> <column name="order_item_id"/> </index> - <index name="DOWNLOADABLE_LINK_PURCHASED_CUSTOMER_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PURCHASED_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> </table> @@ -125,22 +125,22 @@ comment="Creation Time"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Update Time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="item_id"/> </constraint> - <constraint xsi:type="foreign" name="DL_LNK_PURCHASED_ITEM_PURCHASED_ID_DL_LNK_PURCHASED_PURCHASED_ID" + <constraint xsi:type="foreign" referenceId="DL_LNK_PURCHASED_ITEM_PURCHASED_ID_DL_LNK_PURCHASED_PURCHASED_ID" table="downloadable_link_purchased_item" column="purchased_id" referenceTable="downloadable_link_purchased" referenceColumn="purchased_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="DL_LNK_PURCHASED_ITEM_ORDER_ITEM_ID_SALES_ORDER_ITEM_ITEM_ID" + <constraint xsi:type="foreign" referenceId="DL_LNK_PURCHASED_ITEM_ORDER_ITEM_ID_SALES_ORDER_ITEM_ITEM_ID" table="downloadable_link_purchased_item" column="order_item_id" referenceTable="sales_order_item" referenceColumn="item_id" onDelete="SET NULL"/> - <index name="DOWNLOADABLE_LINK_PURCHASED_ITEM_LINK_HASH" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PURCHASED_ITEM_LINK_HASH" indexType="btree"> <column name="link_hash"/> </index> - <index name="DOWNLOADABLE_LINK_PURCHASED_ITEM_ORDER_ITEM_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PURCHASED_ITEM_ORDER_ITEM_ID" indexType="btree"> <column name="order_item_id"/> </index> - <index name="DOWNLOADABLE_LINK_PURCHASED_ITEM_PURCHASED_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_PURCHASED_ITEM_PURCHASED_ID" indexType="btree"> <column name="purchased_id"/> </index> </table> @@ -152,20 +152,20 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store ID"/> <column xsi:type="varchar" name="title" nullable="true" length="255" comment="Title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="title_id"/> </constraint> - <constraint xsi:type="foreign" name="DOWNLOADABLE_LINK_TITLE_LINK_ID_DOWNLOADABLE_LINK_LINK_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_LINK_TITLE_LINK_ID_DOWNLOADABLE_LINK_LINK_ID" table="downloadable_link_title" column="link_id" referenceTable="downloadable_link" referenceColumn="link_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="DOWNLOADABLE_LINK_TITLE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_LINK_TITLE_STORE_ID_STORE_STORE_ID" table="downloadable_link_title" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="DOWNLOADABLE_LINK_TITLE_LINK_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="DOWNLOADABLE_LINK_TITLE_LINK_ID_STORE_ID"> <column name="link_id"/> <column name="store_id"/> </constraint> - <index name="DOWNLOADABLE_LINK_TITLE_STORE_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_LINK_TITLE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -179,13 +179,13 @@ <column xsi:type="varchar" name="sample_type" nullable="true" length="20" comment="Sample Type"/> <column xsi:type="int" name="sort_order" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="sample_id"/> </constraint> - <constraint xsi:type="foreign" name="DOWNLOADABLE_SAMPLE_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_SAMPLE_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="downloadable_sample" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="DOWNLOADABLE_SAMPLE_PRODUCT_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_SAMPLE_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -198,20 +198,20 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store ID"/> <column xsi:type="varchar" name="title" nullable="true" length="255" comment="Title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="title_id"/> </constraint> - <constraint xsi:type="foreign" name="DL_SAMPLE_TTL_SAMPLE_ID_DL_SAMPLE_SAMPLE_ID" + <constraint xsi:type="foreign" referenceId="DL_SAMPLE_TTL_SAMPLE_ID_DL_SAMPLE_SAMPLE_ID" table="downloadable_sample_title" column="sample_id" referenceTable="downloadable_sample" referenceColumn="sample_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="DOWNLOADABLE_SAMPLE_TITLE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="DOWNLOADABLE_SAMPLE_TITLE_STORE_ID_STORE_STORE_ID" table="downloadable_sample_title" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="DOWNLOADABLE_SAMPLE_TITLE_SAMPLE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="DOWNLOADABLE_SAMPLE_TITLE_SAMPLE_ID_STORE_ID"> <column name="sample_id"/> <column name="store_id"/> </constraint> - <index name="DOWNLOADABLE_SAMPLE_TITLE_STORE_ID" indexType="btree"> + <index referenceId="DOWNLOADABLE_SAMPLE_TITLE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -227,7 +227,7 @@ default="0" comment="Minimum price"/> <column xsi:type="decimal" name="max_price" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Maximum price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> @@ -245,7 +245,7 @@ default="0" comment="Minimum price"/> <column xsi:type="decimal" name="max_price" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Maximum price"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="customer_group_id"/> <column name="website_id"/> diff --git a/app/code/Magento/Eav/etc/db_schema.xml b/app/code/Magento/Eav/etc/db_schema.xml index f930321e5259b..c27c3cb32c488 100644 --- a/app/code/Magento/Eav/etc/db_schema.xml +++ b/app/code/Magento/Eav/etc/db_schema.xml @@ -33,10 +33,10 @@ comment="Additional Attribute Table"/> <column xsi:type="varchar" name="entity_attribute_collection" nullable="true" length="255" comment="Entity Attribute Collection"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_type_id"/> </constraint> - <index name="EAV_ENTITY_TYPE_ENTITY_TYPE_CODE" indexType="btree"> + <index referenceId="EAV_ENTITY_TYPE_ENTITY_TYPE_CODE" indexType="btree"> <column name="entity_type_code"/> </index> </table> @@ -58,18 +58,18 @@ comment="Updated At"/> <column xsi:type="smallint" name="is_active" padding="5" unsigned="true" nullable="false" identity="false" default="1" comment="Defines Is Entity Active"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_entity" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_STORE_ID_STORE_STORE_ID" table="eav_entity" column="store_id" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_STORE_ID_STORE_STORE_ID" table="eav_entity" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="EAV_ENTITY_ENTITY_TYPE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_ENTITY_TYPE_ID" indexType="btree"> <column name="entity_type_id"/> </index> - <index name="EAV_ENTITY_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -85,30 +85,30 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Attribute Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_DATETIME_ENTITY_ID_EAV_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_DATETIME_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_datetime" column="entity_id" referenceTable="eav_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTT_DTIME_ENTT_TYPE_ID_EAV_ENTT_TYPE_ENTT_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTT_DTIME_ENTT_TYPE_ID_EAV_ENTT_TYPE_ENTT_TYPE_ID" table="eav_entity_datetime" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" table="eav_entity_datetime" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" table="eav_entity_datetime" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="EAV_ENTITY_DATETIME_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_DATETIME_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="EAV_ENTITY_DATETIME_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_DATETIME_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="attribute_id"/> <column name="value"/> </index> - <index name="EAV_ENTITY_DATETIME_ENTITY_TYPE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_DATETIME_ENTITY_TYPE_ID_VALUE" indexType="btree"> <column name="entity_type_id"/> <column name="value"/> </index> @@ -126,30 +126,30 @@ default="0" comment="Entity Id"/> <column xsi:type="decimal" name="value" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Attribute Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_DECIMAL_ENTITY_ID_EAV_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_DECIMAL_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_decimal" column="entity_id" referenceTable="eav_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_DECIMAL_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_DECIMAL_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_entity_decimal" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_DECIMAL_STORE_ID_STORE_STORE_ID" table="eav_entity_decimal" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_DECIMAL_STORE_ID_STORE_STORE_ID" table="eav_entity_decimal" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_DECIMAL_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="EAV_ENTITY_DECIMAL_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_DECIMAL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="EAV_ENTITY_DECIMAL_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_DECIMAL_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="attribute_id"/> <column name="value"/> </index> - <index name="EAV_ENTITY_DECIMAL_ENTITY_TYPE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_DECIMAL_ENTITY_TYPE_ID_VALUE" indexType="btree"> <column name="entity_type_id"/> <column name="value"/> </index> @@ -167,29 +167,29 @@ default="0" comment="Entity Id"/> <column xsi:type="int" name="value" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Attribute Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_INT_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_int" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_INT_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_int" column="entity_id" referenceTable="eav_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_INT_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_INT_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_entity_int" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_INT_STORE_ID_STORE_STORE_ID" table="eav_entity_int" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_INT_STORE_ID_STORE_STORE_ID" table="eav_entity_int" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="EAV_ENTITY_INT_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_INT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="EAV_ENTITY_INT_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_INT_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="attribute_id"/> <column name="value"/> </index> - <index name="EAV_ENTITY_INT_ENTITY_TYPE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_INT_ENTITY_TYPE_ID_VALUE" indexType="btree"> <column name="entity_type_id"/> <column name="value"/> </index> @@ -206,28 +206,28 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="text" name="value" nullable="false" comment="Attribute Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_TEXT_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_text" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_TEXT_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_text" column="entity_id" referenceTable="eav_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_TEXT_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_TEXT_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_entity_text" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_TEXT_STORE_ID_STORE_STORE_ID" table="eav_entity_text" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_TEXT_STORE_ID_STORE_STORE_ID" table="eav_entity_text" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_TEXT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="EAV_ENTITY_TEXT_ENTITY_TYPE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_TEXT_ENTITY_TYPE_ID" indexType="btree"> <column name="entity_type_id"/> </index> - <index name="EAV_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_TEXT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index name="EAV_ENTITY_TEXT_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_TEXT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -243,30 +243,30 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity Id"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Attribute Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_VARCHAR_ENTITY_ID_EAV_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_VARCHAR_ENTITY_ID_EAV_ENTITY_ENTITY_ID" table="eav_entity_varchar" column="entity_id" referenceTable="eav_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_VARCHAR_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_VARCHAR_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_entity_varchar" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID" table="eav_entity_varchar" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_VARCHAR_STORE_ID_STORE_STORE_ID" table="eav_entity_varchar" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_VARCHAR_ENTITY_ID_ATTRIBUTE_ID_STORE_ID"> <column name="entity_id"/> <column name="attribute_id"/> <column name="store_id"/> </constraint> - <index name="EAV_ENTITY_VARCHAR_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_VARCHAR_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="EAV_ENTITY_VARCHAR_ATTRIBUTE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_VARCHAR_ATTRIBUTE_ID_VALUE" indexType="btree"> <column name="attribute_id"/> <column name="value"/> </index> - <index name="EAV_ENTITY_VARCHAR_ENTITY_TYPE_ID_VALUE" indexType="btree"> + <index referenceId="EAV_ENTITY_VARCHAR_ENTITY_TYPE_ID_VALUE" indexType="btree"> <column name="entity_type_id"/> <column name="value"/> </index> @@ -295,13 +295,13 @@ <column xsi:type="smallint" name="is_unique" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Defines Is Unique"/> <column xsi:type="varchar" name="note" nullable="true" length="255" comment="Note"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_attribute" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ATTRIBUTE_ENTITY_TYPE_ID_ATTRIBUTE_CODE"> + <constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_ENTITY_TYPE_ID_ATTRIBUTE_CODE"> <column name="entity_type_id"/> <column name="attribute_code"/> </constraint> @@ -315,18 +315,18 @@ default="0" comment="Store Id"/> <column xsi:type="varchar" name="increment_prefix" nullable="true" length="20" comment="Increment Prefix"/> <column xsi:type="varchar" name="increment_last_id" nullable="true" length="50" comment="Last Incremented Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_store_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_STORE_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_STORE_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_entity_store" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTITY_STORE_STORE_ID_STORE_STORE_ID" table="eav_entity_store" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_STORE_STORE_ID_STORE_STORE_ID" table="eav_entity_store" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="EAV_ENTITY_STORE_ENTITY_TYPE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_STORE_ENTITY_TYPE_ID" indexType="btree"> <column name="entity_type_id"/> </index> - <index name="EAV_ENTITY_STORE_STORE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_STORE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -338,17 +338,17 @@ <column xsi:type="varchar" name="attribute_set_name" nullable="true" length="255" comment="Attribute Set Name"/> <column xsi:type="smallint" name="sort_order" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_set_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_SET_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_SET_ENTITY_TYPE_ID_EAV_ENTITY_TYPE_ENTITY_TYPE_ID" table="eav_attribute_set" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ATTRIBUTE_SET_ENTITY_TYPE_ID_ATTRIBUTE_SET_NAME"> + <constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_SET_ENTITY_TYPE_ID_ATTRIBUTE_SET_NAME"> <column name="entity_type_id"/> <column name="attribute_set_name"/> </constraint> - <index name="EAV_ATTRIBUTE_SET_ENTITY_TYPE_ID_SORT_ORDER" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_SET_ENTITY_TYPE_ID_SORT_ORDER" indexType="btree"> <column name="entity_type_id"/> <column name="sort_order"/> </index> @@ -367,21 +367,21 @@ <column xsi:type="varchar" name="attribute_group_code" nullable="false" length="255" comment="Attribute Group Code"/> <column xsi:type="varchar" name="tab_group_code" nullable="true" length="255" comment="Tab Group Code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_group_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTR_GROUP_ATTR_SET_ID_EAV_ATTR_SET_ATTR_SET_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTR_GROUP_ATTR_SET_ID_EAV_ATTR_SET_ATTR_SET_ID" table="eav_attribute_group" column="attribute_set_id" referenceTable="eav_attribute_set" referenceColumn="attribute_set_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_NAME"> + <constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_NAME"> <column name="attribute_set_id"/> <column name="attribute_group_name"/> </constraint> - <constraint xsi:type="unique" name="EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_CODE"> + <constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_CODE"> <column name="attribute_set_id"/> <column name="attribute_group_code"/> </constraint> - <index name="EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_SORT_ORDER" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_SORT_ORDER" indexType="btree"> <column name="attribute_set_id"/> <column name="sort_order"/> </index> @@ -399,28 +399,28 @@ default="0" comment="Attribute Id"/> <column xsi:type="smallint" name="sort_order" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="eav_entity_attribute" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ENTT_ATTR_ATTR_GROUP_ID_EAV_ATTR_GROUP_ATTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="EAV_ENTT_ATTR_ATTR_GROUP_ID_EAV_ATTR_GROUP_ATTR_GROUP_ID" table="eav_entity_attribute" column="attribute_group_id" referenceTable="eav_attribute_group" referenceColumn="attribute_group_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_ATTRIBUTE_ID"> <column name="attribute_set_id"/> <column name="attribute_id"/> </constraint> - <constraint xsi:type="unique" name="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_GROUP_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_GROUP_ID_ATTRIBUTE_ID"> <column name="attribute_group_id"/> <column name="attribute_id"/> </constraint> - <index name="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_SORT_ORDER" indexType="btree"> + <index referenceId="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_SET_ID_SORT_ORDER" indexType="btree"> <column name="attribute_set_id"/> <column name="sort_order"/> </index> - <index name="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="EAV_ENTITY_ATTRIBUTE_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -431,13 +431,13 @@ default="0" comment="Attribute Id"/> <column xsi:type="smallint" name="sort_order" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_OPTION_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_OPTION_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="eav_attribute_option" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <index name="EAV_ATTRIBUTE_OPTION_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_OPTION_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -449,19 +449,19 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store Id"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTR_OPT_VAL_OPT_ID_EAV_ATTR_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTR_OPT_VAL_OPT_ID_EAV_ATTR_OPT_OPT_ID" table="eav_attribute_option_value" column="option_id" referenceTable="eav_attribute_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID_STORE_STORE_ID" table="eav_attribute_option_value" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="EAV_ATTRIBUTE_OPTION_VALUE_OPTION_ID" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_OPTION_VALUE_OPTION_ID" indexType="btree"> <column name="option_id"/> </index> - <index name="EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -473,18 +473,18 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store Id"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="attribute_label_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="eav_attribute_label" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_LABEL_STORE_ID_STORE_STORE_ID" table="eav_attribute_label" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_LABEL_STORE_ID_STORE_STORE_ID" table="eav_attribute_label" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="EAV_ATTRIBUTE_LABEL_STORE_ID" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_LABEL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_STORE_ID" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_STORE_ID" indexType="btree"> <column name="attribute_id"/> <column name="store_id"/> </index> @@ -499,17 +499,17 @@ <column xsi:type="varchar" name="theme" nullable="true" length="64" comment="Theme"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="type_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_FORM_TYPE_STORE_ID_STORE_STORE_ID" table="eav_form_type" + <constraint xsi:type="foreign" referenceId="EAV_FORM_TYPE_STORE_ID_STORE_STORE_ID" table="eav_form_type" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_FORM_TYPE_CODE_THEME_STORE_ID"> + <constraint xsi:type="unique" referenceId="EAV_FORM_TYPE_CODE_THEME_STORE_ID"> <column name="code"/> <column name="theme"/> <column name="store_id"/> </constraint> - <index name="EAV_FORM_TYPE_STORE_ID" indexType="btree"> + <index referenceId="EAV_FORM_TYPE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -518,17 +518,17 @@ comment="Type Id"/> <column xsi:type="smallint" name="entity_type_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Entity Type Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="type_id"/> <column name="entity_type_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_FORM_TYPE_ENTT_ENTT_TYPE_ID_EAV_ENTT_TYPE_ENTT_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_FORM_TYPE_ENTT_ENTT_TYPE_ID_EAV_ENTT_TYPE_ENTT_TYPE_ID" table="eav_form_type_entity" column="entity_type_id" referenceTable="eav_entity_type" referenceColumn="entity_type_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_FORM_TYPE_ENTITY_TYPE_ID_EAV_FORM_TYPE_TYPE_ID" + <constraint xsi:type="foreign" referenceId="EAV_FORM_TYPE_ENTITY_TYPE_ID_EAV_FORM_TYPE_TYPE_ID" table="eav_form_type_entity" column="type_id" referenceTable="eav_form_type" referenceColumn="type_id" onDelete="CASCADE"/> - <index name="EAV_FORM_TYPE_ENTITY_ENTITY_TYPE_ID" indexType="btree"> + <index referenceId="EAV_FORM_TYPE_ENTITY_ENTITY_TYPE_ID" indexType="btree"> <column name="entity_type_id"/> </index> </table> @@ -540,12 +540,12 @@ <column xsi:type="varchar" name="code" nullable="false" length="64" comment="Code"/> <column xsi:type="int" name="sort_order" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="fieldset_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_FORM_FIELDSET_TYPE_ID_EAV_FORM_TYPE_TYPE_ID" table="eav_form_fieldset" + <constraint xsi:type="foreign" referenceId="EAV_FORM_FIELDSET_TYPE_ID_EAV_FORM_TYPE_TYPE_ID" table="eav_form_fieldset" column="type_id" referenceTable="eav_form_type" referenceColumn="type_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_FORM_FIELDSET_TYPE_ID_CODE"> + <constraint xsi:type="unique" referenceId="EAV_FORM_FIELDSET_TYPE_ID_CODE"> <column name="type_id"/> <column name="code"/> </constraint> @@ -556,17 +556,17 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> <column xsi:type="varchar" name="label" nullable="false" length="255" comment="Label"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="fieldset_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_FORM_FSET_LBL_FSET_ID_EAV_FORM_FSET_FSET_ID" + <constraint xsi:type="foreign" referenceId="EAV_FORM_FSET_LBL_FSET_ID_EAV_FORM_FSET_FSET_ID" table="eav_form_fieldset_label" column="fieldset_id" referenceTable="eav_form_fieldset" referenceColumn="fieldset_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_FORM_FIELDSET_LABEL_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="EAV_FORM_FIELDSET_LABEL_STORE_ID_STORE_STORE_ID" table="eav_form_fieldset_label" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="EAV_FORM_FIELDSET_LABEL_STORE_ID" indexType="btree"> + <index referenceId="EAV_FORM_FIELDSET_LABEL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -581,25 +581,25 @@ comment="Attribute Id"/> <column xsi:type="int" name="sort_order" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="Sort Order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="element_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_FORM_ELEMENT_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" + <constraint xsi:type="foreign" referenceId="EAV_FORM_ELEMENT_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="eav_form_element" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_FORM_ELEMENT_FIELDSET_ID_EAV_FORM_FIELDSET_FIELDSET_ID" + <constraint xsi:type="foreign" referenceId="EAV_FORM_ELEMENT_FIELDSET_ID_EAV_FORM_FIELDSET_FIELDSET_ID" table="eav_form_element" column="fieldset_id" referenceTable="eav_form_fieldset" referenceColumn="fieldset_id" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="EAV_FORM_ELEMENT_TYPE_ID_EAV_FORM_TYPE_TYPE_ID" table="eav_form_element" + <constraint xsi:type="foreign" referenceId="EAV_FORM_ELEMENT_TYPE_ID_EAV_FORM_TYPE_TYPE_ID" table="eav_form_element" column="type_id" referenceTable="eav_form_type" referenceColumn="type_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_FORM_ELEMENT_TYPE_ID_ATTRIBUTE_ID"> + <constraint xsi:type="unique" referenceId="EAV_FORM_ELEMENT_TYPE_ID_ATTRIBUTE_ID"> <column name="type_id"/> <column name="attribute_id"/> </constraint> - <index name="EAV_FORM_ELEMENT_FIELDSET_ID" indexType="btree"> + <index referenceId="EAV_FORM_ELEMENT_FIELDSET_ID" indexType="btree"> <column name="fieldset_id"/> </index> - <index name="EAV_FORM_ELEMENT_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="EAV_FORM_ELEMENT_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> diff --git a/app/code/Magento/Email/etc/db_schema.xml b/app/code/Magento/Email/etc/db_schema.xml index 53ef349a383ae..dbb8855e9e57e 100644 --- a/app/code/Magento/Email/etc/db_schema.xml +++ b/app/code/Magento/Email/etc/db_schema.xml @@ -27,16 +27,16 @@ <column xsi:type="varchar" name="orig_template_code" nullable="true" length="200" comment="Original Template Code"/> <column xsi:type="text" name="orig_template_variables" nullable="true" comment="Original Template Variables"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="template_id"/> </constraint> - <constraint xsi:type="unique" name="EMAIL_TEMPLATE_TEMPLATE_CODE"> + <constraint xsi:type="unique" referenceId="EMAIL_TEMPLATE_TEMPLATE_CODE"> <column name="template_code"/> </constraint> - <index name="EMAIL_TEMPLATE_ADDED_AT" indexType="btree"> + <index referenceId="EMAIL_TEMPLATE_ADDED_AT" indexType="btree"> <column name="added_at"/> </index> - <index name="EMAIL_TEMPLATE_MODIFIED_AT" indexType="btree"> + <index referenceId="EMAIL_TEMPLATE_MODIFIED_AT" indexType="btree"> <column name="modified_at"/> </index> </table> diff --git a/app/code/Magento/GiftMessage/etc/db_schema.xml b/app/code/Magento/GiftMessage/etc/db_schema.xml index 518c6398e4c8d..4ae98799df0c2 100644 --- a/app/code/Magento/GiftMessage/etc/db_schema.xml +++ b/app/code/Magento/GiftMessage/etc/db_schema.xml @@ -15,7 +15,7 @@ <column xsi:type="varchar" name="sender" nullable="true" length="255" comment="Sender"/> <column xsi:type="varchar" name="recipient" nullable="true" length="255" comment="Registrant"/> <column xsi:type="text" name="message" nullable="true" comment="Message"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="gift_message_id"/> </constraint> </table> diff --git a/app/code/Magento/GoogleOptimizer/etc/db_schema.xml b/app/code/Magento/GoogleOptimizer/etc/db_schema.xml index ad3e03e490b05..76c377544cfb3 100644 --- a/app/code/Magento/GoogleOptimizer/etc/db_schema.xml +++ b/app/code/Magento/GoogleOptimizer/etc/db_schema.xml @@ -16,12 +16,12 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store id"/> <column xsi:type="text" name="experiment_script" nullable="true" comment="Google experiment script"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="code_id"/> </constraint> - <constraint xsi:type="foreign" name="GOOGLEOPTIMIZER_CODE_STORE_ID_STORE_STORE_ID" table="googleoptimizer_code" + <constraint xsi:type="foreign" referenceId="GOOGLEOPTIMIZER_CODE_STORE_ID_STORE_STORE_ID" table="googleoptimizer_code" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="GOOGLEOPTIMIZER_CODE_STORE_ID_ENTITY_ID_ENTITY_TYPE"> + <constraint xsi:type="unique" referenceId="GOOGLEOPTIMIZER_CODE_STORE_ID_ENTITY_ID_ENTITY_TYPE"> <column name="store_id"/> <column name="entity_id"/> <column name="entity_type"/> diff --git a/app/code/Magento/ImportExport/etc/db_schema.xml b/app/code/Magento/ImportExport/etc/db_schema.xml index 01f20daabf0f9..df45131848519 100644 --- a/app/code/Magento/ImportExport/etc/db_schema.xml +++ b/app/code/Magento/ImportExport/etc/db_schema.xml @@ -12,7 +12,7 @@ <column xsi:type="varchar" name="entity" nullable="false" length="50" comment="Entity"/> <column xsi:type="varchar" name="behavior" nullable="false" length="10" default="append" comment="Behavior"/> <column xsi:type="longtext" name="data" nullable="true" comment="Data"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> </table> @@ -27,7 +27,7 @@ <column xsi:type="varchar" name="execution_time" nullable="true" length="255" comment="Execution time"/> <column xsi:type="varchar" name="summary" nullable="true" length="255" comment="Summary"/> <column xsi:type="varchar" name="error_file" nullable="false" length="255" comment="Imported file with errors"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="history_id"/> </constraint> </table> diff --git a/app/code/Magento/Indexer/etc/db_schema.xml b/app/code/Magento/Indexer/etc/db_schema.xml index 58c447f4d262e..d7cb006a2cf45 100644 --- a/app/code/Magento/Indexer/etc/db_schema.xml +++ b/app/code/Magento/Indexer/etc/db_schema.xml @@ -15,10 +15,10 @@ comment="Indexer Status"/> <column xsi:type="datetime" name="updated" on_update="false" nullable="true" comment="Indexer Status"/> <column xsi:type="varchar" name="hash_config" nullable="false" length="32" comment="Hash of indexer config"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="state_id"/> </constraint> - <index name="INDEXER_STATE_INDEXER_ID" indexType="btree"> + <index referenceId="INDEXER_STATE_INDEXER_ID" indexType="btree"> <column name="indexer_id"/> </index> </table> @@ -31,13 +31,13 @@ <column xsi:type="datetime" name="updated" on_update="false" nullable="true" comment="View updated time"/> <column xsi:type="int" name="version_id" padding="10" unsigned="true" nullable="true" identity="false" comment="View Version Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="state_id"/> </constraint> - <index name="MVIEW_STATE_VIEW_ID" indexType="btree"> + <index referenceId="MVIEW_STATE_VIEW_ID" indexType="btree"> <column name="view_id"/> </index> - <index name="MVIEW_STATE_MODE" indexType="btree"> + <index referenceId="MVIEW_STATE_MODE" indexType="btree"> <column name="mode"/> </index> </table> diff --git a/app/code/Magento/Integration/etc/db_schema.xml b/app/code/Magento/Integration/etc/db_schema.xml index 9e81b867d36d5..c2c2cedc665fb 100644 --- a/app/code/Magento/Integration/etc/db_schema.xml +++ b/app/code/Magento/Integration/etc/db_schema.xml @@ -19,19 +19,19 @@ <column xsi:type="varchar" name="secret" nullable="false" length="32" comment="Secret code"/> <column xsi:type="text" name="callback_url" nullable="true" comment="Callback URL"/> <column xsi:type="text" name="rejected_callback_url" nullable="false" comment="Rejected callback URL"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="unique" name="OAUTH_CONSUMER_KEY"> + <constraint xsi:type="unique" referenceId="OAUTH_CONSUMER_KEY"> <column name="key"/> </constraint> - <constraint xsi:type="unique" name="OAUTH_CONSUMER_SECRET"> + <constraint xsi:type="unique" referenceId="OAUTH_CONSUMER_SECRET"> <column name="secret"/> </constraint> - <index name="OAUTH_CONSUMER_CREATED_AT" indexType="btree"> + <index referenceId="OAUTH_CONSUMER_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="OAUTH_CONSUMER_UPDATED_AT" indexType="btree"> + <index referenceId="OAUTH_CONSUMER_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> </table> @@ -57,21 +57,21 @@ comment="User type"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Token creation timestamp"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="OAUTH_TOKEN_ADMIN_ID_ADMIN_USER_USER_ID" table="oauth_token" + <constraint xsi:type="foreign" referenceId="OAUTH_TOKEN_ADMIN_ID_ADMIN_USER_USER_ID" table="oauth_token" column="admin_id" referenceTable="admin_user" referenceColumn="user_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="OAUTH_TOKEN_CONSUMER_ID_OAUTH_CONSUMER_ENTITY_ID" table="oauth_token" + <constraint xsi:type="foreign" referenceId="OAUTH_TOKEN_CONSUMER_ID_OAUTH_CONSUMER_ENTITY_ID" table="oauth_token" column="consumer_id" referenceTable="oauth_consumer" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="OAUTH_TOKEN_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="oauth_token" + <constraint xsi:type="foreign" referenceId="OAUTH_TOKEN_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="oauth_token" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="OAUTH_TOKEN_TOKEN"> + <constraint xsi:type="unique" referenceId="OAUTH_TOKEN_TOKEN"> <column name="token"/> </constraint> - <index name="OAUTH_TOKEN_CONSUMER_ID" indexType="btree"> + <index referenceId="OAUTH_TOKEN_CONSUMER_ID" indexType="btree"> <column name="consumer_id"/> </index> </table> @@ -81,14 +81,14 @@ comment="Nonce Timestamp"/> <column xsi:type="int" name="consumer_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Consumer ID"/> - <constraint xsi:type="foreign" name="OAUTH_NONCE_CONSUMER_ID_OAUTH_CONSUMER_ENTITY_ID" table="oauth_nonce" + <constraint xsi:type="foreign" referenceId="OAUTH_NONCE_CONSUMER_ID_OAUTH_CONSUMER_ENTITY_ID" table="oauth_nonce" column="consumer_id" referenceTable="oauth_consumer" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="OAUTH_NONCE_NONCE_CONSUMER_ID"> + <constraint xsi:type="unique" referenceId="OAUTH_NONCE_NONCE_CONSUMER_ID"> <column name="nonce"/> <column name="consumer_id"/> </constraint> - <index name="OAUTH_NONCE_TIMESTAMP" indexType="btree"> + <index referenceId="OAUTH_NONCE_TIMESTAMP" indexType="btree"> <column name="timestamp"/> </index> </table> @@ -113,16 +113,16 @@ default="0" comment="Integration type - manual or config file"/> <column xsi:type="varchar" name="identity_link_url" nullable="true" length="255" comment="Identity linking Url"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="integration_id"/> </constraint> - <constraint xsi:type="foreign" name="INTEGRATION_CONSUMER_ID_OAUTH_CONSUMER_ENTITY_ID" table="integration" + <constraint xsi:type="foreign" referenceId="INTEGRATION_CONSUMER_ID_OAUTH_CONSUMER_ENTITY_ID" table="integration" column="consumer_id" referenceTable="oauth_consumer" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="INTEGRATION_NAME"> + <constraint xsi:type="unique" referenceId="INTEGRATION_NAME"> <column name="name"/> </constraint> - <constraint xsi:type="unique" name="INTEGRATION_CONSUMER_ID"> + <constraint xsi:type="unique" referenceId="INTEGRATION_CONSUMER_ID"> <column name="consumer_id"/> </constraint> </table> @@ -138,10 +138,10 @@ default="0" comment="Number of failed authentication attempts in a row"/> <column xsi:type="timestamp" name="lock_expires_at" on_update="true" nullable="true" default="CURRENT_TIMESTAMP" comment="Lock expiration time"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="log_id"/> </constraint> - <constraint xsi:type="unique" name="OAUTH_TOKEN_REQUEST_LOG_USER_NAME_USER_TYPE"> + <constraint xsi:type="unique" referenceId="OAUTH_TOKEN_REQUEST_LOG_USER_NAME_USER_TYPE"> <column name="user_name"/> <column name="user_type"/> </constraint> diff --git a/app/code/Magento/MessageQueue/etc/db_schema.xml b/app/code/Magento/MessageQueue/etc/db_schema.xml index 9cbad4d32a889..7a20d2bd4df5d 100644 --- a/app/code/Magento/MessageQueue/etc/db_schema.xml +++ b/app/code/Magento/MessageQueue/etc/db_schema.xml @@ -14,10 +14,10 @@ <column xsi:type="varchar" name="message_code" nullable="false" length="255" default="" comment="Message Code"/> <column xsi:type="timestamp" name="created_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Created At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="unique" name="QUEUE_LOCK_MESSAGE_CODE"> + <constraint xsi:type="unique" referenceId="QUEUE_LOCK_MESSAGE_CODE"> <column name="message_code"/> </constraint> </table> diff --git a/app/code/Magento/MysqlMq/etc/db_schema.xml b/app/code/Magento/MysqlMq/etc/db_schema.xml index 02757afa53fcd..3850a6749a3d6 100644 --- a/app/code/Magento/MysqlMq/etc/db_schema.xml +++ b/app/code/Magento/MysqlMq/etc/db_schema.xml @@ -11,10 +11,10 @@ <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="Queue ID"/> <column xsi:type="varchar" name="name" nullable="true" length="255" comment="Queue name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="unique" name="QUEUE_NAME"> + <constraint xsi:type="unique" referenceId="QUEUE_NAME"> <column name="name"/> </constraint> </table> @@ -23,7 +23,7 @@ comment="Message ID"/> <column xsi:type="varchar" name="topic_name" nullable="true" length="255" comment="Message topic"/> <column xsi:type="longtext" name="body" nullable="true" comment="Message body"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> </table> @@ -41,19 +41,19 @@ comment="Message status in particular queue"/> <column xsi:type="smallint" name="number_of_trials" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Number of trials to processed failed message processing"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="QUEUE_MESSAGE_STATUS_MESSAGE_ID_QUEUE_MESSAGE_ID" + <constraint xsi:type="foreign" referenceId="QUEUE_MESSAGE_STATUS_MESSAGE_ID_QUEUE_MESSAGE_ID" table="queue_message_status" column="message_id" referenceTable="queue_message" referenceColumn="id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="QUEUE_MESSAGE_STATUS_QUEUE_ID_QUEUE_ID" table="queue_message_status" + <constraint xsi:type="foreign" referenceId="QUEUE_MESSAGE_STATUS_QUEUE_ID_QUEUE_ID" table="queue_message_status" column="queue_id" referenceTable="queue" referenceColumn="id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="QUEUE_MESSAGE_STATUS_QUEUE_ID_MESSAGE_ID"> + <constraint xsi:type="unique" referenceId="QUEUE_MESSAGE_STATUS_QUEUE_ID_MESSAGE_ID"> <column name="queue_id"/> <column name="message_id"/> </constraint> - <index name="QUEUE_MESSAGE_STATUS_STATUS_UPDATED_AT" indexType="btree"> + <index referenceId="QUEUE_MESSAGE_STATUS_STATUS_UPDATED_AT" indexType="btree"> <column name="status"/> <column name="updated_at"/> </index> diff --git a/app/code/Magento/NewRelicReporting/etc/db_schema.xml b/app/code/Magento/NewRelicReporting/etc/db_schema.xml index 6f9ce29436f65..ff23f3210111e 100644 --- a/app/code/Magento/NewRelicReporting/etc/db_schema.xml +++ b/app/code/Magento/NewRelicReporting/etc/db_schema.xml @@ -16,7 +16,7 @@ comment="Count Value"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> </table> @@ -29,7 +29,7 @@ <column xsi:type="varchar" name="state" nullable="true" length="255" comment="Module State"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> </table> @@ -44,7 +44,7 @@ comment="Line Item Count"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> </table> @@ -55,7 +55,7 @@ <column xsi:type="varchar" name="action" nullable="true" length="255" comment="Action Performed"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> </table> @@ -66,7 +66,7 @@ <column xsi:type="varchar" name="action" nullable="true" length="255" comment="Action Performed"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> </table> diff --git a/app/code/Magento/Newsletter/etc/db_schema.xml b/app/code/Magento/Newsletter/etc/db_schema.xml index 5084b8b6d01e7..5cb572f41b6be 100644 --- a/app/code/Magento/Newsletter/etc/db_schema.xml +++ b/app/code/Magento/Newsletter/etc/db_schema.xml @@ -21,19 +21,19 @@ default="0" comment="Subscriber Status"/> <column xsi:type="varchar" name="subscriber_confirm_code" nullable="true" length="32" default="NULL" comment="Subscriber Confirm Code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="subscriber_id"/> </constraint> - <constraint xsi:type="foreign" name="NEWSLETTER_SUBSCRIBER_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="NEWSLETTER_SUBSCRIBER_STORE_ID_STORE_STORE_ID" table="newsletter_subscriber" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="NEWSLETTER_SUBSCRIBER_CUSTOMER_ID" indexType="btree"> + <index referenceId="NEWSLETTER_SUBSCRIBER_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="NEWSLETTER_SUBSCRIBER_STORE_ID" indexType="btree"> + <index referenceId="NEWSLETTER_SUBSCRIBER_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="NEWSLETTER_SUBSCRIBER_SUBSCRIBER_EMAIL" indexType="btree"> + <index referenceId="NEWSLETTER_SUBSCRIBER_SUBSCRIBER_EMAIL" indexType="btree"> <column name="subscriber_email"/> </index> </table> @@ -54,16 +54,16 @@ default="1" comment="Template Actual"/> <column xsi:type="timestamp" name="added_at" on_update="false" nullable="true" comment="Added At"/> <column xsi:type="timestamp" name="modified_at" on_update="false" nullable="true" comment="Modified At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="template_id"/> </constraint> - <index name="NEWSLETTER_TEMPLATE_TEMPLATE_ACTUAL" indexType="btree"> + <index referenceId="NEWSLETTER_TEMPLATE_TEMPLATE_ACTUAL" indexType="btree"> <column name="template_actual"/> </index> - <index name="NEWSLETTER_TEMPLATE_ADDED_AT" indexType="btree"> + <index referenceId="NEWSLETTER_TEMPLATE_ADDED_AT" indexType="btree"> <column name="added_at"/> </index> - <index name="NEWSLETTER_TEMPLATE_MODIFIED_AT" indexType="btree"> + <index referenceId="NEWSLETTER_TEMPLATE_MODIFIED_AT" indexType="btree"> <column name="modified_at"/> </index> </table> @@ -86,13 +86,13 @@ <column xsi:type="timestamp" name="queue_start_at" on_update="false" nullable="true" comment="Queue Start At"/> <column xsi:type="timestamp" name="queue_finish_at" on_update="false" nullable="true" comment="Queue Finish At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="queue_id"/> </constraint> - <constraint xsi:type="foreign" name="NEWSLETTER_QUEUE_TEMPLATE_ID_NEWSLETTER_TEMPLATE_TEMPLATE_ID" + <constraint xsi:type="foreign" referenceId="NEWSLETTER_QUEUE_TEMPLATE_ID_NEWSLETTER_TEMPLATE_TEMPLATE_ID" table="newsletter_queue" column="template_id" referenceTable="newsletter_template" referenceColumn="template_id" onDelete="CASCADE"/> - <index name="NEWSLETTER_QUEUE_TEMPLATE_ID" indexType="btree"> + <index referenceId="NEWSLETTER_QUEUE_TEMPLATE_ID" indexType="btree"> <column name="template_id"/> </index> </table> @@ -104,19 +104,19 @@ <column xsi:type="int" name="subscriber_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Subscriber Id"/> <column xsi:type="timestamp" name="letter_sent_at" on_update="false" nullable="true" comment="Letter Sent At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="queue_link_id"/> </constraint> - <constraint xsi:type="foreign" name="NEWSLETTER_QUEUE_LINK_QUEUE_ID_NEWSLETTER_QUEUE_QUEUE_ID" + <constraint xsi:type="foreign" referenceId="NEWSLETTER_QUEUE_LINK_QUEUE_ID_NEWSLETTER_QUEUE_QUEUE_ID" table="newsletter_queue_link" column="queue_id" referenceTable="newsletter_queue" referenceColumn="queue_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="NLTTR_QUEUE_LNK_SUBSCRIBER_ID_NLTTR_SUBSCRIBER_SUBSCRIBER_ID" + <constraint xsi:type="foreign" referenceId="NLTTR_QUEUE_LNK_SUBSCRIBER_ID_NLTTR_SUBSCRIBER_SUBSCRIBER_ID" table="newsletter_queue_link" column="subscriber_id" referenceTable="newsletter_subscriber" referenceColumn="subscriber_id" onDelete="CASCADE"/> - <index name="NEWSLETTER_QUEUE_LINK_SUBSCRIBER_ID" indexType="btree"> + <index referenceId="NEWSLETTER_QUEUE_LINK_SUBSCRIBER_ID" indexType="btree"> <column name="subscriber_id"/> </index> - <index name="NEWSLETTER_QUEUE_LINK_QUEUE_ID_LETTER_SENT_AT" indexType="btree"> + <index referenceId="NEWSLETTER_QUEUE_LINK_QUEUE_ID_LETTER_SENT_AT" indexType="btree"> <column name="queue_id"/> <column name="letter_sent_at"/> </index> @@ -126,17 +126,17 @@ default="0" comment="Queue Id"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="queue_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="NEWSLETTER_QUEUE_STORE_LINK_QUEUE_ID_NEWSLETTER_QUEUE_QUEUE_ID" + <constraint xsi:type="foreign" referenceId="NEWSLETTER_QUEUE_STORE_LINK_QUEUE_ID_NEWSLETTER_QUEUE_QUEUE_ID" table="newsletter_queue_store_link" column="queue_id" referenceTable="newsletter_queue" referenceColumn="queue_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="NEWSLETTER_QUEUE_STORE_LINK_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="NEWSLETTER_QUEUE_STORE_LINK_STORE_ID_STORE_STORE_ID" table="newsletter_queue_store_link" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="NEWSLETTER_QUEUE_STORE_LINK_STORE_ID" indexType="btree"> + <index referenceId="NEWSLETTER_QUEUE_STORE_LINK_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -150,19 +150,19 @@ <column xsi:type="int" name="problem_error_code" padding="10" unsigned="true" nullable="true" identity="false" default="0" comment="Problem Error Code"/> <column xsi:type="varchar" name="problem_error_text" nullable="true" length="200" comment="Problem Error Text"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="problem_id"/> </constraint> - <constraint xsi:type="foreign" name="NEWSLETTER_PROBLEM_QUEUE_ID_NEWSLETTER_QUEUE_QUEUE_ID" + <constraint xsi:type="foreign" referenceId="NEWSLETTER_PROBLEM_QUEUE_ID_NEWSLETTER_QUEUE_QUEUE_ID" table="newsletter_problem" column="queue_id" referenceTable="newsletter_queue" referenceColumn="queue_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="NLTTR_PROBLEM_SUBSCRIBER_ID_NLTTR_SUBSCRIBER_SUBSCRIBER_ID" + <constraint xsi:type="foreign" referenceId="NLTTR_PROBLEM_SUBSCRIBER_ID_NLTTR_SUBSCRIBER_SUBSCRIBER_ID" table="newsletter_problem" column="subscriber_id" referenceTable="newsletter_subscriber" referenceColumn="subscriber_id" onDelete="CASCADE"/> - <index name="NEWSLETTER_PROBLEM_SUBSCRIBER_ID" indexType="btree"> + <index referenceId="NEWSLETTER_PROBLEM_SUBSCRIBER_ID" indexType="btree"> <column name="subscriber_id"/> </index> - <index name="NEWSLETTER_PROBLEM_QUEUE_ID" indexType="btree"> + <index referenceId="NEWSLETTER_PROBLEM_QUEUE_ID" indexType="btree"> <column name="queue_id"/> </index> </table> diff --git a/app/code/Magento/OfflineShipping/etc/db_schema.xml b/app/code/Magento/OfflineShipping/etc/db_schema.xml index 80f4b56a1723d..0510ce9b9b8eb 100644 --- a/app/code/Magento/OfflineShipping/etc/db_schema.xml +++ b/app/code/Magento/OfflineShipping/etc/db_schema.xml @@ -25,10 +25,10 @@ comment="Price"/> <column xsi:type="decimal" name="cost" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Cost"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="pk"/> </constraint> - <constraint xsi:type="unique" name="UNQ_D60821CDB2AFACEE1566CFC02D0D4CAA"> + <constraint xsi:type="unique" referenceId="UNQ_D60821CDB2AFACEE1566CFC02D0D4CAA"> <column name="website_id"/> <column name="dest_country_id"/> <column name="dest_region_id"/> diff --git a/app/code/Magento/Paypal/etc/db_schema.xml b/app/code/Magento/Paypal/etc/db_schema.xml index 2703ee4f5be30..2d7874453a6d9 100644 --- a/app/code/Magento/Paypal/etc/db_schema.xml +++ b/app/code/Magento/Paypal/etc/db_schema.xml @@ -21,19 +21,19 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="true" identity="false" comment="Store Id"/> <column xsi:type="varchar" name="agreement_label" nullable="true" length="255" comment="Agreement Label"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="agreement_id"/> </constraint> - <constraint xsi:type="foreign" name="PAYPAL_BILLING_AGREEMENT_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PAYPAL_BILLING_AGREEMENT_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="paypal_billing_agreement" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PAYPAL_BILLING_AGREEMENT_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="PAYPAL_BILLING_AGREEMENT_STORE_ID_STORE_STORE_ID" table="paypal_billing_agreement" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="PAYPAL_BILLING_AGREEMENT_CUSTOMER_ID" indexType="btree"> + <index referenceId="PAYPAL_BILLING_AGREEMENT_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="PAYPAL_BILLING_AGREEMENT_STORE_ID" indexType="btree"> + <index referenceId="PAYPAL_BILLING_AGREEMENT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -43,17 +43,17 @@ comment="Agreement Id"/> <column xsi:type="int" name="order_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Order Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="agreement_id"/> <column name="order_id"/> </constraint> - <constraint xsi:type="foreign" name="PAYPAL_BILLING_AGRT_ORDER_AGRT_ID_PAYPAL_BILLING_AGRT_AGRT_ID" + <constraint xsi:type="foreign" referenceId="PAYPAL_BILLING_AGRT_ORDER_AGRT_ID_PAYPAL_BILLING_AGRT_AGRT_ID" table="paypal_billing_agreement_order" column="agreement_id" referenceTable="paypal_billing_agreement" referenceColumn="agreement_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PAYPAL_BILLING_AGREEMENT_ORDER_ORDER_ID_SALES_ORDER_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PAYPAL_BILLING_AGREEMENT_ORDER_ORDER_ID_SALES_ORDER_ENTITY_ID" table="paypal_billing_agreement_order" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="PAYPAL_BILLING_AGREEMENT_ORDER_ORDER_ID" indexType="btree"> + <index referenceId="PAYPAL_BILLING_AGREEMENT_ORDER_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> </table> @@ -64,10 +64,10 @@ <column xsi:type="varchar" name="account_id" nullable="true" length="64" comment="Account Id"/> <column xsi:type="varchar" name="filename" nullable="true" length="24" comment="Filename"/> <column xsi:type="timestamp" name="last_modified" on_update="false" nullable="true" comment="Last Modified"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="report_id"/> </constraint> - <constraint xsi:type="unique" name="PAYPAL_SETTLEMENT_REPORT_REPORT_DATE_ACCOUNT_ID"> + <constraint xsi:type="unique" referenceId="PAYPAL_SETTLEMENT_REPORT_REPORT_DATE_ACCOUNT_ID"> <column name="report_date"/> <column name="account_id"/> </constraint> @@ -105,13 +105,13 @@ <column xsi:type="varchar" name="payment_tracking_id" nullable="true" length="255" comment="Payment Tracking ID"/> <column xsi:type="varchar" name="store_id" nullable="true" length="50" comment="Store ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="row_id"/> </constraint> - <constraint xsi:type="foreign" name="FK_E183E488F593E0DE10C6EBFFEBAC9B55" table="paypal_settlement_report_row" + <constraint xsi:type="foreign" referenceId="FK_E183E488F593E0DE10C6EBFFEBAC9B55" table="paypal_settlement_report_row" column="report_id" referenceTable="paypal_settlement_report" referenceColumn="report_id" onDelete="CASCADE"/> - <index name="PAYPAL_SETTLEMENT_REPORT_ROW_REPORT_ID" indexType="btree"> + <index referenceId="PAYPAL_SETTLEMENT_REPORT_ROW_REPORT_ID" indexType="btree"> <column name="report_id"/> </index> </table> @@ -122,12 +122,12 @@ default="0" comment="Website Id"/> <column xsi:type="text" name="content" nullable="true" comment="Content"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="true" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="cert_id"/> </constraint> - <constraint xsi:type="foreign" name="PAYPAL_CERT_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="paypal_cert" + <constraint xsi:type="foreign" referenceId="PAYPAL_CERT_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="paypal_cert" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="PAYPAL_CERT_WEBSITE_ID" indexType="btree"> + <index referenceId="PAYPAL_CERT_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -138,10 +138,10 @@ <column xsi:type="varchar" name="txn_id" nullable="true" length="100" comment="Txn Id"/> <column xsi:type="blob" name="additional_information" nullable="true" comment="Additional Information"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="true" comment="Created At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="transaction_id"/> </constraint> - <constraint xsi:type="unique" name="PAYPAL_PAYMENT_TRANSACTION_TXN_ID"> + <constraint xsi:type="unique" referenceId="PAYPAL_PAYMENT_TRANSACTION_TXN_ID"> <column name="txn_id"/> </constraint> </table> diff --git a/app/code/Magento/Persistent/etc/db_schema.xml b/app/code/Magento/Persistent/etc/db_schema.xml index 68678fc60f096..5021d240417b2 100644 --- a/app/code/Magento/Persistent/etc/db_schema.xml +++ b/app/code/Magento/Persistent/etc/db_schema.xml @@ -18,22 +18,22 @@ <column xsi:type="text" name="info" nullable="true" comment="Session Data"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="persistent_id"/> </constraint> - <constraint xsi:type="foreign" name="PERSISTENT_SESSION_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PERSISTENT_SESSION_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="persistent_session" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PERSISTENT_SESSION_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="PERSISTENT_SESSION_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="persistent_session" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="PERSISTENT_SESSION_KEY"> + <constraint xsi:type="unique" referenceId="PERSISTENT_SESSION_KEY"> <column name="key"/> </constraint> - <constraint xsi:type="unique" name="PERSISTENT_SESSION_CUSTOMER_ID"> + <constraint xsi:type="unique" referenceId="PERSISTENT_SESSION_CUSTOMER_ID"> <column name="customer_id"/> </constraint> - <index name="PERSISTENT_SESSION_UPDATED_AT" indexType="btree"> + <index referenceId="PERSISTENT_SESSION_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> </table> diff --git a/app/code/Magento/ProductAlert/etc/db_schema.xml b/app/code/Magento/ProductAlert/etc/db_schema.xml index ddf8be8a37e9c..62f0eda16afa1 100644 --- a/app/code/Magento/ProductAlert/etc/db_schema.xml +++ b/app/code/Magento/ProductAlert/etc/db_schema.xml @@ -26,25 +26,25 @@ default="0" comment="Product alert send count"/> <column xsi:type="smallint" name="status" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Product alert status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="alert_price_id"/> </constraint> - <constraint xsi:type="foreign" name="PRODUCT_ALERT_PRICE_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PRODUCT_ALERT_PRICE_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="product_alert_price" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PRODUCT_ALERT_PRICE_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PRODUCT_ALERT_PRICE_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="product_alert_price" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PRODUCT_ALERT_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="PRODUCT_ALERT_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="product_alert_price" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="PRODUCT_ALERT_PRICE_CUSTOMER_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_PRICE_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="PRODUCT_ALERT_PRICE_PRODUCT_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_PRICE_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> - <index name="PRODUCT_ALERT_PRICE_WEBSITE_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -65,25 +65,25 @@ default="0" comment="Send Count"/> <column xsi:type="smallint" name="status" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Product alert status"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="alert_stock_id"/> </constraint> - <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="PRODUCT_ALERT_STOCK_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="product_alert_stock" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PRODUCT_ALERT_STOCK_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="product_alert_stock" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="PRODUCT_ALERT_STOCK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="PRODUCT_ALERT_STOCK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="product_alert_stock" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="PRODUCT_ALERT_STOCK_CUSTOMER_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_STOCK_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="PRODUCT_ALERT_STOCK_PRODUCT_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_STOCK_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> - <index name="PRODUCT_ALERT_STOCK_WEBSITE_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_STOCK_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> diff --git a/app/code/Magento/ProductVideo/etc/db_schema.xml b/app/code/Magento/ProductVideo/etc/db_schema.xml index ceaf4d7fbd85d..bfe087d9a5769 100644 --- a/app/code/Magento/ProductVideo/etc/db_schema.xml +++ b/app/code/Magento/ProductVideo/etc/db_schema.xml @@ -18,14 +18,14 @@ <column xsi:type="varchar" name="title" nullable="true" length="255" comment="Title"/> <column xsi:type="text" name="description" nullable="true" comment="Page Meta Description"/> <column xsi:type="text" name="metadata" nullable="true" comment="Video meta data"/> - <constraint xsi:type="foreign" name="FK_6FDF205946906B0E653E60AA769899F8" + <constraint xsi:type="foreign" referenceId="FK_6FDF205946906B0E653E60AA769899F8" table="catalog_product_entity_media_gallery_value_video" column="value_id" referenceTable="catalog_product_entity_media_gallery" referenceColumn="value_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="CAT_PRD_ENTT_MDA_GLR_VAL_VIDEO_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_VIDEO_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_media_gallery_value_video" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="CAT_PRD_ENTT_MDA_GLR_VAL_VIDEO_VAL_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_VIDEO_VAL_ID_STORE_ID"> <column name="value_id"/> <column name="store_id"/> </constraint> diff --git a/app/code/Magento/Quote/etc/db_schema.xml b/app/code/Magento/Quote/etc/db_schema.xml index 3bd7122e65d7f..8e399f03afecd 100644 --- a/app/code/Magento/Quote/etc/db_schema.xml +++ b/app/code/Magento/Quote/etc/db_schema.xml @@ -87,17 +87,17 @@ <column xsi:type="smallint" name="trigger_recollect" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Trigger Recollect"/> <column xsi:type="text" name="ext_shipping_info" nullable="true" comment="Ext Shipping Info"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_STORE_ID_STORE_STORE_ID" table="quote" column="store_id" + <constraint xsi:type="foreign" referenceId="QUOTE_STORE_ID_STORE_STORE_ID" table="quote" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="QUOTE_CUSTOMER_ID_STORE_ID_IS_ACTIVE" indexType="btree"> + <index referenceId="QUOTE_CUSTOMER_ID_STORE_ID_IS_ACTIVE" indexType="btree"> <column name="customer_id"/> <column name="store_id"/> <column name="is_active"/> </index> - <index name="QUOTE_STORE_ID" indexType="btree"> + <index referenceId="QUOTE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -202,12 +202,12 @@ <column xsi:type="text" name="vat_request_date" nullable="true" comment="Vat Request Date"/> <column xsi:type="smallint" name="vat_request_success" padding="6" unsigned="false" nullable="true" identity="false" comment="Vat Request Success"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="address_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_ADDRESS_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_address" + <constraint xsi:type="foreign" referenceId="QUOTE_ADDRESS_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_address" column="quote_id" referenceTable="quote" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="QUOTE_ADDRESS_QUOTE_ID" indexType="btree"> + <index referenceId="QUOTE_ADDRESS_QUOTE_ID" indexType="btree"> <column name="quote_id"/> </index> </table> @@ -289,25 +289,25 @@ nullable="true" comment="Discount Tax Compensation Amount"/> <column xsi:type="decimal" name="base_discount_tax_compensation_amount" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Discount Tax Compensation Amount"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="item_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_ITEM_PARENT_ITEM_ID_QUOTE_ITEM_ITEM_ID" table="quote_item" + <constraint xsi:type="foreign" referenceId="QUOTE_ITEM_PARENT_ITEM_ID_QUOTE_ITEM_ITEM_ID" table="quote_item" column="parent_item_id" referenceTable="quote_item" referenceColumn="item_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="QUOTE_ITEM_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_item" column="quote_id" + <constraint xsi:type="foreign" referenceId="QUOTE_ITEM_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_item" column="quote_id" referenceTable="quote" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="QUOTE_ITEM_STORE_ID_STORE_STORE_ID" table="quote_item" column="store_id" + <constraint xsi:type="foreign" referenceId="QUOTE_ITEM_STORE_ID_STORE_STORE_ID" table="quote_item" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="QUOTE_ITEM_PARENT_ITEM_ID" indexType="btree"> + <index referenceId="QUOTE_ITEM_PARENT_ITEM_ID" indexType="btree"> <column name="parent_item_id"/> </index> - <index name="QUOTE_ITEM_PRODUCT_ID" indexType="btree"> + <index referenceId="QUOTE_ITEM_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> - <index name="QUOTE_ITEM_QUOTE_ID" indexType="btree"> + <index referenceId="QUOTE_ITEM_QUOTE_ID" indexType="btree"> <column name="quote_id"/> </index> - <index name="QUOTE_ITEM_STORE_ID" indexType="btree"> + <index referenceId="QUOTE_ITEM_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -382,25 +382,25 @@ nullable="true" comment="Discount Tax Compensation Amount"/> <column xsi:type="decimal" name="base_discount_tax_compensation_amount" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Discount Tax Compensation Amount"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="address_item_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_ADDRESS_ITEM_QUOTE_ADDRESS_ID_QUOTE_ADDRESS_ADDRESS_ID" + <constraint xsi:type="foreign" referenceId="QUOTE_ADDRESS_ITEM_QUOTE_ADDRESS_ID_QUOTE_ADDRESS_ADDRESS_ID" table="quote_address_item" column="quote_address_id" referenceTable="quote_address" referenceColumn="address_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="QUOTE_ADDR_ITEM_PARENT_ITEM_ID_QUOTE_ADDR_ITEM_ADDR_ITEM_ID" + <constraint xsi:type="foreign" referenceId="QUOTE_ADDR_ITEM_PARENT_ITEM_ID_QUOTE_ADDR_ITEM_ADDR_ITEM_ID" table="quote_address_item" column="parent_item_id" referenceTable="quote_address_item" referenceColumn="address_item_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="QUOTE_ADDRESS_ITEM_QUOTE_ITEM_ID_QUOTE_ITEM_ITEM_ID" + <constraint xsi:type="foreign" referenceId="QUOTE_ADDRESS_ITEM_QUOTE_ITEM_ID_QUOTE_ITEM_ITEM_ID" table="quote_address_item" column="quote_item_id" referenceTable="quote_item" referenceColumn="item_id" onDelete="CASCADE"/> - <index name="QUOTE_ADDRESS_ITEM_QUOTE_ADDRESS_ID" indexType="btree"> + <index referenceId="QUOTE_ADDRESS_ITEM_QUOTE_ADDRESS_ID" indexType="btree"> <column name="quote_address_id"/> </index> - <index name="QUOTE_ADDRESS_ITEM_PARENT_ITEM_ID" indexType="btree"> + <index referenceId="QUOTE_ADDRESS_ITEM_PARENT_ITEM_ID" indexType="btree"> <column name="parent_item_id"/> </index> - <index name="QUOTE_ADDRESS_ITEM_QUOTE_ITEM_ID" indexType="btree"> + <index referenceId="QUOTE_ADDRESS_ITEM_QUOTE_ITEM_ID" indexType="btree"> <column name="quote_item_id"/> </index> </table> @@ -413,12 +413,12 @@ comment="Product Id"/> <column xsi:type="varchar" name="code" nullable="false" length="255" comment="Code"/> <column xsi:type="text" name="value" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_ITEM_OPTION_ITEM_ID_QUOTE_ITEM_ITEM_ID" table="quote_item_option" + <constraint xsi:type="foreign" referenceId="QUOTE_ITEM_OPTION_ITEM_ID_QUOTE_ITEM_ITEM_ID" table="quote_item_option" column="item_id" referenceTable="quote_item" referenceColumn="item_id" onDelete="CASCADE"/> - <index name="QUOTE_ITEM_OPTION_ITEM_ID" indexType="btree"> + <index referenceId="QUOTE_ITEM_OPTION_ITEM_ID" indexType="btree"> <column name="item_id"/> </index> </table> @@ -449,12 +449,12 @@ <column xsi:type="text" name="additional_data" nullable="true" comment="Additional Data"/> <column xsi:type="varchar" name="cc_ss_issue" nullable="true" length="255" comment="Cc Ss Issue"/> <column xsi:type="text" name="additional_information" nullable="true" comment="Additional Information"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="payment_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_PAYMENT_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_payment" + <constraint xsi:type="foreign" referenceId="QUOTE_PAYMENT_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_payment" column="quote_id" referenceTable="quote" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="QUOTE_PAYMENT_QUOTE_ID" indexType="btree"> + <index referenceId="QUOTE_PAYMENT_QUOTE_ID" indexType="btree"> <column name="quote_id"/> </index> </table> @@ -476,13 +476,13 @@ comment="Price"/> <column xsi:type="text" name="error_message" nullable="true" comment="Error Message"/> <column xsi:type="text" name="method_title" nullable="true" comment="Method Title"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rate_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_SHIPPING_RATE_ADDRESS_ID_QUOTE_ADDRESS_ADDRESS_ID" + <constraint xsi:type="foreign" referenceId="QUOTE_SHIPPING_RATE_ADDRESS_ID_QUOTE_ADDRESS_ADDRESS_ID" table="quote_shipping_rate" column="address_id" referenceTable="quote_address" referenceColumn="address_id" onDelete="CASCADE"/> - <index name="QUOTE_SHIPPING_RATE_ADDRESS_ID" indexType="btree"> + <index referenceId="QUOTE_SHIPPING_RATE_ADDRESS_ID" indexType="btree"> <column name="address_id"/> </index> </table> @@ -492,16 +492,16 @@ <column xsi:type="int" name="quote_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Quote ID"/> <column xsi:type="varchar" name="masked_id" nullable="true" length="32" comment="Masked ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> <column name="quote_id"/> </constraint> - <constraint xsi:type="foreign" name="QUOTE_ID_MASK_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_id_mask" + <constraint xsi:type="foreign" referenceId="QUOTE_ID_MASK_QUOTE_ID_QUOTE_ENTITY_ID" table="quote_id_mask" column="quote_id" referenceTable="quote" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="QUOTE_ID_MASK_QUOTE_ID" indexType="btree"> + <index referenceId="QUOTE_ID_MASK_QUOTE_ID" indexType="btree"> <column name="quote_id"/> </index> - <index name="QUOTE_ID_MASK_MASKED_ID" indexType="btree"> + <index referenceId="QUOTE_ID_MASK_MASKED_ID" indexType="btree"> <column name="masked_id"/> </index> </table> diff --git a/app/code/Magento/ReleaseNotification/etc/db_schema.xml b/app/code/Magento/ReleaseNotification/etc/db_schema.xml index 367957fc17732..6f3aa481f73d4 100644 --- a/app/code/Magento/ReleaseNotification/etc/db_schema.xml +++ b/app/code/Magento/ReleaseNotification/etc/db_schema.xml @@ -15,13 +15,13 @@ comment="Viewer admin user ID"/> <column xsi:type="varchar" name="last_view_version" nullable="false" length="16" comment="Viewer last view on product version"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="RELEASE_NOTIFICATION_VIEWER_LOG_VIEWER_ID_ADMIN_USER_USER_ID" + <constraint xsi:type="foreign" referenceId="RELEASE_NOTIFICATION_VIEWER_LOG_VIEWER_ID_ADMIN_USER_USER_ID" table="release_notification_viewer_log" column="viewer_id" referenceTable="admin_user" referenceColumn="user_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="RELEASE_NOTIFICATION_VIEWER_LOG_VIEWER_ID"> + <constraint xsi:type="unique" referenceId="RELEASE_NOTIFICATION_VIEWER_LOG_VIEWER_ID"> <column name="viewer_id"/> </constraint> </table> diff --git a/app/code/Magento/Reports/etc/db_schema.xml b/app/code/Magento/Reports/etc/db_schema.xml index f6c8074411bfc..1321ebba4d3d6 100644 --- a/app/code/Magento/Reports/etc/db_schema.xml +++ b/app/code/Magento/Reports/etc/db_schema.xml @@ -21,33 +21,33 @@ comment="Store Id"/> <column xsi:type="timestamp" name="added_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Added At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="index_id"/> </constraint> - <constraint xsi:type="foreign" name="REPORT_CMPD_PRD_IDX_CSTR_ID_CSTR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_CMPD_PRD_IDX_CSTR_ID_CSTR_ENTT_ENTT_ID" table="report_compared_product_index" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_CMPD_PRD_IDX_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_CMPD_PRD_IDX_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="report_compared_product_index" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_COMPARED_PRODUCT_INDEX_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="REPORT_COMPARED_PRODUCT_INDEX_STORE_ID_STORE_STORE_ID" table="report_compared_product_index" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="REPORT_COMPARED_PRODUCT_INDEX_VISITOR_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="REPORT_COMPARED_PRODUCT_INDEX_VISITOR_ID_PRODUCT_ID"> <column name="visitor_id"/> <column name="product_id"/> </constraint> - <constraint xsi:type="unique" name="REPORT_COMPARED_PRODUCT_INDEX_CUSTOMER_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="REPORT_COMPARED_PRODUCT_INDEX_CUSTOMER_ID_PRODUCT_ID"> <column name="customer_id"/> <column name="product_id"/> </constraint> - <index name="REPORT_COMPARED_PRODUCT_INDEX_STORE_ID" indexType="btree"> + <index referenceId="REPORT_COMPARED_PRODUCT_INDEX_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="REPORT_COMPARED_PRODUCT_INDEX_ADDED_AT" indexType="btree"> + <index referenceId="REPORT_COMPARED_PRODUCT_INDEX_ADDED_AT" indexType="btree"> <column name="added_at"/> </index> - <index name="REPORT_COMPARED_PRODUCT_INDEX_PRODUCT_ID" indexType="btree"> + <index referenceId="REPORT_COMPARED_PRODUCT_INDEX_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -65,33 +65,33 @@ comment="Store Id"/> <column xsi:type="timestamp" name="added_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Added At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="index_id"/> </constraint> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRD_IDX_CSTR_ID_CSTR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRD_IDX_CSTR_ID_CSTR_ENTT_ENTT_ID" table="report_viewed_product_index" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRD_IDX_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRD_IDX_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="report_viewed_product_index" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRODUCT_INDEX_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRODUCT_INDEX_STORE_ID_STORE_STORE_ID" table="report_viewed_product_index" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="REPORT_VIEWED_PRODUCT_INDEX_VISITOR_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="REPORT_VIEWED_PRODUCT_INDEX_VISITOR_ID_PRODUCT_ID"> <column name="visitor_id"/> <column name="product_id"/> </constraint> - <constraint xsi:type="unique" name="REPORT_VIEWED_PRODUCT_INDEX_CUSTOMER_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="REPORT_VIEWED_PRODUCT_INDEX_CUSTOMER_ID_PRODUCT_ID"> <column name="customer_id"/> <column name="product_id"/> </constraint> - <index name="REPORT_VIEWED_PRODUCT_INDEX_STORE_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_INDEX_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="REPORT_VIEWED_PRODUCT_INDEX_ADDED_AT" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_INDEX_ADDED_AT" indexType="btree"> <column name="added_at"/> </index> - <index name="REPORT_VIEWED_PRODUCT_INDEX_PRODUCT_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_INDEX_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -101,7 +101,7 @@ <column xsi:type="varchar" name="event_name" nullable="false" length="64" comment="Event Name"/> <column xsi:type="smallint" name="customer_login" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Customer Login"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="event_type_id"/> </constraint> </table> @@ -120,27 +120,27 @@ default="0" comment="Subtype"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="event_id"/> </constraint> - <constraint xsi:type="foreign" name="REPORT_EVENT_STORE_ID_STORE_STORE_ID" table="report_event" + <constraint xsi:type="foreign" referenceId="REPORT_EVENT_STORE_ID_STORE_STORE_ID" table="report_event" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_EVENT_EVENT_TYPE_ID_REPORT_EVENT_TYPES_EVENT_TYPE_ID" + <constraint xsi:type="foreign" referenceId="REPORT_EVENT_EVENT_TYPE_ID_REPORT_EVENT_TYPES_EVENT_TYPE_ID" table="report_event" column="event_type_id" referenceTable="report_event_types" referenceColumn="event_type_id" onDelete="CASCADE"/> - <index name="REPORT_EVENT_EVENT_TYPE_ID" indexType="btree"> + <index referenceId="REPORT_EVENT_EVENT_TYPE_ID" indexType="btree"> <column name="event_type_id"/> </index> - <index name="REPORT_EVENT_SUBJECT_ID" indexType="btree"> + <index referenceId="REPORT_EVENT_SUBJECT_ID" indexType="btree"> <column name="subject_id"/> </index> - <index name="REPORT_EVENT_OBJECT_ID" indexType="btree"> + <index referenceId="REPORT_EVENT_OBJECT_ID" indexType="btree"> <column name="object_id"/> </index> - <index name="REPORT_EVENT_SUBTYPE" indexType="btree"> + <index referenceId="REPORT_EVENT_SUBTYPE" indexType="btree"> <column name="subtype"/> </index> - <index name="REPORT_EVENT_STORE_ID" indexType="btree"> + <index referenceId="REPORT_EVENT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -159,24 +159,24 @@ default="0" comment="Number of Views"/> <column xsi:type="smallint" name="rating_pos" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Rating Pos"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRODUCT_AGGREGATED_DAILY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_DAILY_STORE_ID_STORE_STORE_ID" table="report_viewed_product_aggregated_daily" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRD_AGGRED_DAILY_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRD_AGGRED_DAILY_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="report_viewed_product_aggregated_daily" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="REPORT_VIEWED_PRD_AGGRED_DAILY_PERIOD_STORE_ID_PRD_ID"> + <constraint xsi:type="unique" referenceId="REPORT_VIEWED_PRD_AGGRED_DAILY_PERIOD_STORE_ID_PRD_ID"> <column name="period"/> <column name="store_id"/> <column name="product_id"/> </constraint> - <index name="REPORT_VIEWED_PRODUCT_AGGREGATED_DAILY_STORE_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_DAILY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="REPORT_VIEWED_PRODUCT_AGGREGATED_DAILY_PRODUCT_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_DAILY_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -195,24 +195,24 @@ default="0" comment="Number of Views"/> <column xsi:type="smallint" name="rating_pos" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Rating Pos"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRODUCT_AGGREGATED_MONTHLY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_MONTHLY_STORE_ID_STORE_STORE_ID" table="report_viewed_product_aggregated_monthly" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRD_AGGRED_MONTHLY_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRD_AGGRED_MONTHLY_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="report_viewed_product_aggregated_monthly" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="REPORT_VIEWED_PRD_AGGRED_MONTHLY_PERIOD_STORE_ID_PRD_ID"> + <constraint xsi:type="unique" referenceId="REPORT_VIEWED_PRD_AGGRED_MONTHLY_PERIOD_STORE_ID_PRD_ID"> <column name="period"/> <column name="store_id"/> <column name="product_id"/> </constraint> - <index name="REPORT_VIEWED_PRODUCT_AGGREGATED_MONTHLY_STORE_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_MONTHLY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="REPORT_VIEWED_PRODUCT_AGGREGATED_MONTHLY_PRODUCT_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_MONTHLY_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -231,24 +231,24 @@ default="0" comment="Number of Views"/> <column xsi:type="smallint" name="rating_pos" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Rating Pos"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRODUCT_AGGREGATED_YEARLY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_YEARLY_STORE_ID_STORE_STORE_ID" table="report_viewed_product_aggregated_yearly" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REPORT_VIEWED_PRD_AGGRED_YEARLY_PRD_ID_CAT_PRD_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="REPORT_VIEWED_PRD_AGGRED_YEARLY_PRD_ID_CAT_PRD_ENTT_ENTT_ID" table="report_viewed_product_aggregated_yearly" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="REPORT_VIEWED_PRD_AGGRED_YEARLY_PERIOD_STORE_ID_PRD_ID"> + <constraint xsi:type="unique" referenceId="REPORT_VIEWED_PRD_AGGRED_YEARLY_PERIOD_STORE_ID_PRD_ID"> <column name="period"/> <column name="store_id"/> <column name="product_id"/> </constraint> - <index name="REPORT_VIEWED_PRODUCT_AGGREGATED_YEARLY_STORE_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_YEARLY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="REPORT_VIEWED_PRODUCT_AGGREGATED_YEARLY_PRODUCT_ID" indexType="btree"> + <index referenceId="REPORT_VIEWED_PRODUCT_AGGREGATED_YEARLY_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> diff --git a/app/code/Magento/Review/etc/db_schema.xml b/app/code/Magento/Review/etc/db_schema.xml index 1a2ff588180ce..65cc4d01fed2d 100644 --- a/app/code/Magento/Review/etc/db_schema.xml +++ b/app/code/Magento/Review/etc/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="smallint" name="entity_id" padding="5" unsigned="true" nullable="false" identity="true" comment="Review entity id"/> <column xsi:type="varchar" name="entity_code" nullable="false" length="32" comment="Review entity code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> </table> @@ -19,7 +19,7 @@ <column xsi:type="smallint" name="status_id" padding="5" unsigned="true" nullable="false" identity="true" comment="Status id"/> <column xsi:type="varchar" name="status_code" nullable="false" length="32" comment="Status code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="status_id"/> </constraint> </table> @@ -34,20 +34,20 @@ default="0" comment="Product id"/> <column xsi:type="smallint" name="status_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Status code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="review_id"/> </constraint> - <constraint xsi:type="foreign" name="REVIEW_ENTITY_ID_REVIEW_ENTITY_ENTITY_ID" table="review" column="entity_id" + <constraint xsi:type="foreign" referenceId="REVIEW_ENTITY_ID_REVIEW_ENTITY_ENTITY_ID" table="review" column="entity_id" referenceTable="review_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REVIEW_STATUS_ID_REVIEW_STATUS_STATUS_ID" table="review" column="status_id" + <constraint xsi:type="foreign" referenceId="REVIEW_STATUS_ID_REVIEW_STATUS_STATUS_ID" table="review" column="status_id" referenceTable="review_status" referenceColumn="status_id" onDelete="NO ACTION"/> - <index name="REVIEW_ENTITY_ID" indexType="btree"> + <index referenceId="REVIEW_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="REVIEW_STATUS_ID" indexType="btree"> + <index referenceId="REVIEW_STATUS_ID" indexType="btree"> <column name="status_id"/> </index> - <index name="REVIEW_ENTITY_PK_VALUE" indexType="btree"> + <index referenceId="REVIEW_ENTITY_PK_VALUE" indexType="btree"> <column name="entity_pk_value"/> </index> </table> @@ -63,23 +63,23 @@ <column xsi:type="varchar" name="nickname" nullable="false" length="128" comment="User nickname"/> <column xsi:type="int" name="customer_id" padding="10" unsigned="true" nullable="true" identity="false" comment="Customer Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="detail_id"/> </constraint> - <constraint xsi:type="foreign" name="REVIEW_DETAIL_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="review_detail" + <constraint xsi:type="foreign" referenceId="REVIEW_DETAIL_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="review_detail" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="REVIEW_DETAIL_REVIEW_ID_REVIEW_REVIEW_ID" table="review_detail" + <constraint xsi:type="foreign" referenceId="REVIEW_DETAIL_REVIEW_ID_REVIEW_REVIEW_ID" table="review_detail" column="review_id" referenceTable="review" referenceColumn="review_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REVIEW_DETAIL_STORE_ID_STORE_STORE_ID" table="review_detail" + <constraint xsi:type="foreign" referenceId="REVIEW_DETAIL_STORE_ID_STORE_STORE_ID" table="review_detail" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="REVIEW_DETAIL_REVIEW_ID" indexType="btree"> + <index referenceId="REVIEW_DETAIL_REVIEW_ID" indexType="btree"> <column name="review_id"/> </index> - <index name="REVIEW_DETAIL_STORE_ID" indexType="btree"> + <index referenceId="REVIEW_DETAIL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="REVIEW_DETAIL_CUSTOMER_ID" indexType="btree"> + <index referenceId="REVIEW_DETAIL_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> </table> @@ -96,13 +96,13 @@ default="0" comment="Summarized rating"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="primary_id"/> </constraint> - <constraint xsi:type="foreign" name="REVIEW_ENTITY_SUMMARY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="REVIEW_ENTITY_SUMMARY_STORE_ID_STORE_STORE_ID" table="review_entity_summary" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="REVIEW_ENTITY_SUMMARY_STORE_ID" indexType="btree"> + <index referenceId="REVIEW_ENTITY_SUMMARY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -111,15 +111,15 @@ comment="Review Id"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="review_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="REVIEW_STORE_REVIEW_ID_REVIEW_REVIEW_ID" table="review_store" + <constraint xsi:type="foreign" referenceId="REVIEW_STORE_REVIEW_ID_REVIEW_REVIEW_ID" table="review_store" column="review_id" referenceTable="review" referenceColumn="review_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="REVIEW_STORE_STORE_ID_STORE_STORE_ID" table="review_store" + <constraint xsi:type="foreign" referenceId="REVIEW_STORE_STORE_ID_STORE_STORE_ID" table="review_store" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="REVIEW_STORE_STORE_ID" indexType="btree"> + <index referenceId="REVIEW_STORE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -127,10 +127,10 @@ <column xsi:type="smallint" name="entity_id" padding="5" unsigned="true" nullable="false" identity="true" comment="Entity Id"/> <column xsi:type="varchar" name="entity_code" nullable="false" length="64" comment="Entity Code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="unique" name="RATING_ENTITY_ENTITY_CODE"> + <constraint xsi:type="unique" referenceId="RATING_ENTITY_ENTITY_CODE"> <column name="entity_code"/> </constraint> </table> @@ -144,15 +144,15 @@ default="0" comment="Rating Position On Storefront"/> <column xsi:type="smallint" name="is_active" padding="6" unsigned="false" nullable="false" identity="false" default="1" comment="Rating is active."/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rating_id"/> </constraint> - <constraint xsi:type="foreign" name="RATING_ENTITY_ID_RATING_ENTITY_ENTITY_ID" table="rating" column="entity_id" + <constraint xsi:type="foreign" referenceId="RATING_ENTITY_ID_RATING_ENTITY_ENTITY_ID" table="rating" column="entity_id" referenceTable="rating_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="RATING_RATING_CODE"> + <constraint xsi:type="unique" referenceId="RATING_RATING_CODE"> <column name="rating_code"/> </constraint> - <index name="RATING_ENTITY_ID" indexType="btree"> + <index referenceId="RATING_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> </table> @@ -166,12 +166,12 @@ default="0" comment="Rating Option Value"/> <column xsi:type="smallint" name="position" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Ration option position on Storefront"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_id"/> </constraint> - <constraint xsi:type="foreign" name="RATING_OPTION_RATING_ID_RATING_RATING_ID" table="rating_option" + <constraint xsi:type="foreign" referenceId="RATING_OPTION_RATING_ID_RATING_RATING_ID" table="rating_option" column="rating_id" referenceTable="rating" referenceColumn="rating_id" onDelete="CASCADE"/> - <index name="RATING_OPTION_RATING_ID" indexType="btree"> + <index referenceId="RATING_OPTION_RATING_ID" indexType="btree"> <column name="rating_id"/> </index> </table> @@ -195,15 +195,15 @@ default="0" comment="Percent amount"/> <column xsi:type="smallint" name="value" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Vote option value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="vote_id"/> </constraint> - <constraint xsi:type="foreign" name="RATING_OPTION_VOTE_OPTION_ID_RATING_OPTION_OPTION_ID" + <constraint xsi:type="foreign" referenceId="RATING_OPTION_VOTE_OPTION_ID_RATING_OPTION_OPTION_ID" table="rating_option_vote" column="option_id" referenceTable="rating_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="RATING_OPTION_VOTE_REVIEW_ID_REVIEW_REVIEW_ID" table="rating_option_vote" + <constraint xsi:type="foreign" referenceId="RATING_OPTION_VOTE_REVIEW_ID_REVIEW_REVIEW_ID" table="rating_option_vote" column="review_id" referenceTable="review" referenceColumn="review_id" onDelete="CASCADE"/> - <index name="RATING_OPTION_VOTE_OPTION_ID" indexType="btree"> + <index referenceId="RATING_OPTION_VOTE_OPTION_ID" indexType="btree"> <column name="option_id"/> </index> </table> @@ -224,19 +224,19 @@ identity="false" default="0" comment="Vote percent approved by admin"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="primary_id"/> </constraint> - <constraint xsi:type="foreign" name="RATING_OPTION_VOTE_AGGREGATED_RATING_ID_RATING_RATING_ID" + <constraint xsi:type="foreign" referenceId="RATING_OPTION_VOTE_AGGREGATED_RATING_ID_RATING_RATING_ID" table="rating_option_vote_aggregated" column="rating_id" referenceTable="rating" referenceColumn="rating_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="RATING_OPTION_VOTE_AGGREGATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="RATING_OPTION_VOTE_AGGREGATED_STORE_ID_STORE_STORE_ID" table="rating_option_vote_aggregated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="RATING_OPTION_VOTE_AGGREGATED_RATING_ID" indexType="btree"> + <index referenceId="RATING_OPTION_VOTE_AGGREGATED_RATING_ID" indexType="btree"> <column name="rating_id"/> </index> - <index name="RATING_OPTION_VOTE_AGGREGATED_STORE_ID" indexType="btree"> + <index referenceId="RATING_OPTION_VOTE_AGGREGATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -245,15 +245,15 @@ default="0" comment="Rating id"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rating_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="RATING_STORE_STORE_ID_STORE_STORE_ID" table="rating_store" + <constraint xsi:type="foreign" referenceId="RATING_STORE_STORE_ID_STORE_STORE_ID" table="rating_store" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="RATING_STORE_RATING_ID_RATING_RATING_ID" table="rating_store" + <constraint xsi:type="foreign" referenceId="RATING_STORE_RATING_ID_RATING_RATING_ID" table="rating_store" column="rating_id" referenceTable="rating" referenceColumn="rating_id" onDelete="CASCADE"/> - <index name="RATING_STORE_STORE_ID" indexType="btree"> + <index referenceId="RATING_STORE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -263,15 +263,15 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store Id"/> <column xsi:type="varchar" name="value" nullable="false" length="255" comment="Rating Label"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rating_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="RATING_TITLE_RATING_ID_RATING_RATING_ID" table="rating_title" + <constraint xsi:type="foreign" referenceId="RATING_TITLE_RATING_ID_RATING_RATING_ID" table="rating_title" column="rating_id" referenceTable="rating" referenceColumn="rating_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="RATING_TITLE_STORE_ID_STORE_STORE_ID" table="rating_title" + <constraint xsi:type="foreign" referenceId="RATING_TITLE_STORE_ID_STORE_STORE_ID" table="rating_title" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="RATING_TITLE_STORE_ID" indexType="btree"> + <index referenceId="RATING_TITLE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/Sales/etc/db_schema.xml b/app/code/Magento/Sales/etc/db_schema.xml index 4b716e761094c..6847b4681de52 100644 --- a/app/code/Magento/Sales/etc/db_schema.xml +++ b/app/code/Magento/Sales/etc/db_schema.xml @@ -252,46 +252,46 @@ nullable="true" comment="Base Shipping Incl Tax"/> <column xsi:type="varchar" name="coupon_rule_name" nullable="true" length="255" comment="Coupon Sales Rule Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="sales_order" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="sales_order" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="SALES_ORDER_STORE_ID_STORE_STORE_ID" table="sales_order" column="store_id" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_STORE_ID_STORE_STORE_ID" table="sales_order" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_ORDER_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_ORDER_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_ORDER_STATUS" indexType="btree"> + <index referenceId="SALES_ORDER_STATUS" indexType="btree"> <column name="status"/> </index> - <index name="SALES_ORDER_STATE" indexType="btree"> + <index referenceId="SALES_ORDER_STATE" indexType="btree"> <column name="state"/> </index> - <index name="SALES_ORDER_STORE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_ORDER_CREATED_AT" indexType="btree"> + <index referenceId="SALES_ORDER_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_ORDER_CUSTOMER_ID" indexType="btree"> + <index referenceId="SALES_ORDER_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="SALES_ORDER_EXT_ORDER_ID" indexType="btree"> + <index referenceId="SALES_ORDER_EXT_ORDER_ID" indexType="btree"> <column name="ext_order_id"/> </index> - <index name="SALES_ORDER_QUOTE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_QUOTE_ID" indexType="btree"> <column name="quote_id"/> </index> - <index name="SALES_ORDER_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_ORDER_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_ORDER_SEND_EMAIL" indexType="btree"> + <index referenceId="SALES_ORDER_SEND_EMAIL" indexType="btree"> <column name="send_email"/> </index> - <index name="SALES_ORDER_EMAIL_SENT" indexType="btree"> + <index referenceId="SALES_ORDER_EMAIL_SENT" indexType="btree"> <column name="email_sent"/> </index> </table> @@ -334,47 +334,47 @@ <column xsi:type="varchar" name="payment_method" nullable="true" length="255" comment="Payment Method"/> <column xsi:type="decimal" name="total_refunded" scale="4" precision="12" unsigned="false" nullable="true" comment="Total Refunded"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="unique" name="SALES_ORDER_GRID_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_ORDER_GRID_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_ORDER_GRID_STATUS" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_STATUS" indexType="btree"> <column name="status"/> </index> - <index name="SALES_ORDER_GRID_STORE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_ORDER_GRID_BASE_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_BASE_GRAND_TOTAL" indexType="btree"> <column name="base_grand_total"/> </index> - <index name="SALES_ORDER_GRID_BASE_TOTAL_PAID" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_BASE_TOTAL_PAID" indexType="btree"> <column name="base_total_paid"/> </index> - <index name="SALES_ORDER_GRID_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_GRAND_TOTAL" indexType="btree"> <column name="grand_total"/> </index> - <index name="SALES_ORDER_GRID_TOTAL_PAID" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_TOTAL_PAID" indexType="btree"> <column name="total_paid"/> </index> - <index name="SALES_ORDER_GRID_SHIPPING_NAME" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_SHIPPING_NAME" indexType="btree"> <column name="shipping_name"/> </index> - <index name="SALES_ORDER_GRID_BILLING_NAME" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_BILLING_NAME" indexType="btree"> <column name="billing_name"/> </index> - <index name="SALES_ORDER_GRID_CREATED_AT" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_ORDER_GRID_CUSTOMER_ID" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> - <index name="SALES_ORDER_GRID_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_ORDER_GRID_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="FTI_65B9E9925EC58F0C7C2E2F6379C233E7" indexType="fulltext"> + <index referenceId="FTI_65B9E9925EC58F0C7C2E2F6379C233E7" indexType="fulltext"> <column name="increment_id"/> <column name="billing_name"/> <column name="shipping_name"/> @@ -419,13 +419,13 @@ <column xsi:type="text" name="vat_request_date" nullable="true" comment="Vat Request Date"/> <column xsi:type="smallint" name="vat_request_success" padding="6" unsigned="false" nullable="true" identity="false" comment="Vat Request Success"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_ADDRESS_PARENT_ID_SALES_ORDER_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_ADDRESS_PARENT_ID_SALES_ORDER_ENTITY_ID" table="sales_order_address" column="parent_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_ORDER_ADDRESS_PARENT_ID" indexType="btree"> + <index referenceId="SALES_ORDER_ADDRESS_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -444,16 +444,16 @@ comment="Created At"/> <column xsi:type="varchar" name="entity_name" nullable="true" length="32" comment="Shows what entity history is bind to."/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_STATUS_HISTORY_PARENT_ID_SALES_ORDER_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_STATUS_HISTORY_PARENT_ID_SALES_ORDER_ENTITY_ID" table="sales_order_status_history" column="parent_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_ORDER_STATUS_HISTORY_PARENT_ID" indexType="btree"> + <index referenceId="SALES_ORDER_STATUS_HISTORY_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> - <index name="SALES_ORDER_STATUS_HISTORY_CREATED_AT" indexType="btree"> + <index referenceId="SALES_ORDER_STATUS_HISTORY_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> </table> @@ -586,17 +586,17 @@ comment="Discount Refunded"/> <column xsi:type="decimal" name="base_discount_refunded" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Discount Refunded"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="item_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_ITEM_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_order_item" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_ITEM_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_order_item" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_ORDER_ITEM_STORE_ID_STORE_STORE_ID" table="sales_order_item" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_ITEM_STORE_ID_STORE_STORE_ID" table="sales_order_item" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="SALES_ORDER_ITEM_ORDER_ID" indexType="btree"> + <index referenceId="SALES_ORDER_ITEM_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="SALES_ORDER_ITEM_STORE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_ITEM_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -684,13 +684,13 @@ <column xsi:type="varchar" name="cc_trans_id" nullable="true" length="32" comment="Cc Trans Id"/> <column xsi:type="varchar" name="address_status" nullable="true" length="32" comment="Address Status"/> <column xsi:type="text" name="additional_information" nullable="true" comment="Additional Information"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_PAYMENT_PARENT_ID_SALES_ORDER_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_PAYMENT_PARENT_ID_SALES_ORDER_ENTITY_ID" table="sales_order_payment" column="parent_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_ORDER_PAYMENT_PARENT_ID" indexType="btree"> + <index referenceId="SALES_ORDER_PAYMENT_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -727,36 +727,36 @@ <column xsi:type="text" name="customer_note" nullable="true" comment="Customer Note"/> <column xsi:type="smallint" name="customer_note_notify" padding="5" unsigned="true" nullable="true" identity="false" comment="Customer Note Notify"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SHIPMENT_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_shipment" + <constraint xsi:type="foreign" referenceId="SALES_SHIPMENT_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_shipment" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_SHIPMENT_STORE_ID_STORE_STORE_ID" table="sales_shipment" + <constraint xsi:type="foreign" referenceId="SALES_SHIPMENT_STORE_ID_STORE_STORE_ID" table="sales_shipment" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_SHIPMENT_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_SHIPMENT_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_SHIPMENT_STORE_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_SHIPMENT_TOTAL_QTY" indexType="btree"> + <index referenceId="SALES_SHIPMENT_TOTAL_QTY" indexType="btree"> <column name="total_qty"/> </index> - <index name="SALES_SHIPMENT_ORDER_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="SALES_SHIPMENT_CREATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_SHIPMENT_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_SHIPMENT_SEND_EMAIL" indexType="btree"> + <index referenceId="SALES_SHIPMENT_SEND_EMAIL" indexType="btree"> <column name="send_email"/> </index> - <index name="SALES_SHIPMENT_EMAIL_SENT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_EMAIL_SENT" indexType="btree"> <column name="email_sent"/> </index> </table> @@ -788,44 +788,44 @@ comment="Shipping Method Name"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="true" comment="Created At"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="true" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="unique" name="SALES_SHIPMENT_GRID_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_SHIPMENT_GRID_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_SHIPMENT_GRID_STORE_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_SHIPMENT_GRID_TOTAL_QTY" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_TOTAL_QTY" indexType="btree"> <column name="total_qty"/> </index> - <index name="SALES_SHIPMENT_GRID_ORDER_INCREMENT_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_ORDER_INCREMENT_ID" indexType="btree"> <column name="order_increment_id"/> </index> - <index name="SALES_SHIPMENT_GRID_SHIPMENT_STATUS" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_SHIPMENT_STATUS" indexType="btree"> <column name="shipment_status"/> </index> - <index name="SALES_SHIPMENT_GRID_ORDER_STATUS" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_ORDER_STATUS" indexType="btree"> <column name="order_status"/> </index> - <index name="SALES_SHIPMENT_GRID_CREATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_SHIPMENT_GRID_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_SHIPMENT_GRID_ORDER_CREATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_ORDER_CREATED_AT" indexType="btree"> <column name="order_created_at"/> </index> - <index name="SALES_SHIPMENT_GRID_SHIPPING_NAME" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_SHIPPING_NAME" indexType="btree"> <column name="shipping_name"/> </index> - <index name="SALES_SHIPMENT_GRID_BILLING_NAME" indexType="btree"> + <index referenceId="SALES_SHIPMENT_GRID_BILLING_NAME" indexType="btree"> <column name="billing_name"/> </index> - <index name="FTI_086B40C8955F167B8EA76653437879B4" indexType="fulltext"> + <index referenceId="FTI_086B40C8955F167B8EA76653437879B4" indexType="fulltext"> <column name="increment_id"/> <column name="order_increment_id"/> <column name="shipping_name"/> @@ -855,13 +855,13 @@ <column xsi:type="text" name="description" nullable="true" comment="Description"/> <column xsi:type="varchar" name="name" nullable="true" length="255" comment="Name"/> <column xsi:type="varchar" name="sku" nullable="true" length="255" comment="Sku"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SHIPMENT_ITEM_PARENT_ID_SALES_SHIPMENT_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_SHIPMENT_ITEM_PARENT_ID_SALES_SHIPMENT_ENTITY_ID" table="sales_shipment_item" column="parent_id" referenceTable="sales_shipment" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_SHIPMENT_ITEM_PARENT_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_ITEM_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -883,19 +883,19 @@ comment="Created At"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SHIPMENT_TRACK_PARENT_ID_SALES_SHIPMENT_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_SHIPMENT_TRACK_PARENT_ID_SALES_SHIPMENT_ENTITY_ID" table="sales_shipment_track" column="parent_id" referenceTable="sales_shipment" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_SHIPMENT_TRACK_PARENT_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_TRACK_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> - <index name="SALES_SHIPMENT_TRACK_ORDER_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_TRACK_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="SALES_SHIPMENT_TRACK_CREATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_TRACK_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> </table> @@ -911,16 +911,16 @@ <column xsi:type="text" name="comment" nullable="true" comment="Comment"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Created At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SHIPMENT_COMMENT_PARENT_ID_SALES_SHIPMENT_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_SHIPMENT_COMMENT_PARENT_ID_SALES_SHIPMENT_ENTITY_ID" table="sales_shipment_comment" column="parent_id" referenceTable="sales_shipment" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_SHIPMENT_COMMENT_CREATED_AT" indexType="btree"> + <index referenceId="SALES_SHIPMENT_COMMENT_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_SHIPMENT_COMMENT_PARENT_ID" indexType="btree"> + <index referenceId="SALES_SHIPMENT_COMMENT_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -1013,39 +1013,39 @@ <column xsi:type="text" name="customer_note" nullable="true" comment="Customer Note"/> <column xsi:type="smallint" name="customer_note_notify" padding="5" unsigned="true" nullable="true" identity="false" comment="Customer Note Notify"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_INVOICE_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_invoice" + <constraint xsi:type="foreign" referenceId="SALES_INVOICE_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_invoice" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_INVOICE_STORE_ID_STORE_STORE_ID" table="sales_invoice" + <constraint xsi:type="foreign" referenceId="SALES_INVOICE_STORE_ID_STORE_STORE_ID" table="sales_invoice" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_INVOICE_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_INVOICE_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_INVOICE_STORE_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_INVOICE_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_INVOICE_GRAND_TOTAL" indexType="btree"> <column name="grand_total"/> </index> - <index name="SALES_INVOICE_ORDER_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="SALES_INVOICE_STATE" indexType="btree"> + <index referenceId="SALES_INVOICE_STATE" indexType="btree"> <column name="state"/> </index> - <index name="SALES_INVOICE_CREATED_AT" indexType="btree"> + <index referenceId="SALES_INVOICE_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_INVOICE_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_INVOICE_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_INVOICE_SEND_EMAIL" indexType="btree"> + <index referenceId="SALES_INVOICE_SEND_EMAIL" indexType="btree"> <column name="send_email"/> </index> - <index name="SALES_INVOICE_EMAIL_SENT" indexType="btree"> + <index referenceId="SALES_INVOICE_EMAIL_SENT" indexType="btree"> <column name="email_sent"/> </index> </table> @@ -1087,41 +1087,41 @@ <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="true" comment="Updated At"/> <column xsi:type="decimal" name="base_grand_total" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Grand Total"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="unique" name="SALES_INVOICE_GRID_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_INVOICE_GRID_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_INVOICE_GRID_STORE_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_INVOICE_GRID_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_GRAND_TOTAL" indexType="btree"> <column name="grand_total"/> </index> - <index name="SALES_INVOICE_GRID_ORDER_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="SALES_INVOICE_GRID_STATE" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_STATE" indexType="btree"> <column name="state"/> </index> - <index name="SALES_INVOICE_GRID_ORDER_INCREMENT_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_ORDER_INCREMENT_ID" indexType="btree"> <column name="order_increment_id"/> </index> - <index name="SALES_INVOICE_GRID_CREATED_AT" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_INVOICE_GRID_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_INVOICE_GRID_ORDER_CREATED_AT" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_ORDER_CREATED_AT" indexType="btree"> <column name="order_created_at"/> </index> - <index name="SALES_INVOICE_GRID_BILLING_NAME" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_BILLING_NAME" indexType="btree"> <column name="billing_name"/> </index> - <index name="FTI_95D9C924DD6A8734EB8B5D01D60F90DE" indexType="fulltext"> + <index referenceId="FTI_95D9C924DD6A8734EB8B5D01D60F90DE" indexType="fulltext"> <column name="increment_id"/> <column name="order_increment_id"/> <column name="billing_name"/> @@ -1130,7 +1130,7 @@ <column name="customer_name"/> <column name="customer_email"/> </index> - <index name="SALES_INVOICE_GRID_BASE_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_INVOICE_GRID_BASE_GRAND_TOTAL" indexType="btree"> <column name="base_grand_total"/> </index> </table> @@ -1180,13 +1180,13 @@ unsigned="false" nullable="true" comment="Base Discount Tax Compensation Amount"/> <column xsi:type="text" name="tax_ratio" nullable="true" comment="Ratio of tax invoiced over tax of the order item"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_INVOICE_ITEM_PARENT_ID_SALES_INVOICE_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_INVOICE_ITEM_PARENT_ID_SALES_INVOICE_ENTITY_ID" table="sales_invoice_item" column="parent_id" referenceTable="sales_invoice" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_INVOICE_ITEM_PARENT_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_ITEM_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -1202,16 +1202,16 @@ <column xsi:type="text" name="comment" nullable="true" comment="Comment"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Created At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_INVOICE_COMMENT_PARENT_ID_SALES_INVOICE_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_INVOICE_COMMENT_PARENT_ID_SALES_INVOICE_ENTITY_ID" table="sales_invoice_comment" column="parent_id" referenceTable="sales_invoice" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_INVOICE_COMMENT_CREATED_AT" indexType="btree"> + <index referenceId="SALES_INVOICE_COMMENT_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_INVOICE_COMMENT_PARENT_ID" indexType="btree"> + <index referenceId="SALES_INVOICE_COMMENT_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -1312,39 +1312,39 @@ <column xsi:type="text" name="customer_note" nullable="true" comment="Customer Note"/> <column xsi:type="smallint" name="customer_note_notify" padding="5" unsigned="true" nullable="true" identity="false" comment="Customer Note Notify"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_CREDITMEMO_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_creditmemo" + <constraint xsi:type="foreign" referenceId="SALES_CREDITMEMO_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_creditmemo" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_CREDITMEMO_STORE_ID_STORE_STORE_ID" table="sales_creditmemo" + <constraint xsi:type="foreign" referenceId="SALES_CREDITMEMO_STORE_ID_STORE_STORE_ID" table="sales_creditmemo" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_CREDITMEMO_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_CREDITMEMO_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_CREDITMEMO_STORE_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_CREDITMEMO_ORDER_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="SALES_CREDITMEMO_CREDITMEMO_STATUS" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_CREDITMEMO_STATUS" indexType="btree"> <column name="creditmemo_status"/> </index> - <index name="SALES_CREDITMEMO_STATE" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_STATE" indexType="btree"> <column name="state"/> </index> - <index name="SALES_CREDITMEMO_CREATED_AT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_CREDITMEMO_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_CREDITMEMO_SEND_EMAIL" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_SEND_EMAIL" indexType="btree"> <column name="send_email"/> </index> - <index name="SALES_CREDITMEMO_EMAIL_SENT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_EMAIL_SENT" indexType="btree"> <column name="email_sent"/> </index> </table> @@ -1386,47 +1386,47 @@ comment="Adjustment Negative"/> <column xsi:type="decimal" name="order_base_grand_total" scale="4" precision="12" unsigned="false" nullable="true" comment="Order Grand Total"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="unique" name="SALES_CREDITMEMO_GRID_INCREMENT_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_CREDITMEMO_GRID_INCREMENT_ID_STORE_ID"> <column name="increment_id"/> <column name="store_id"/> </constraint> - <index name="SALES_CREDITMEMO_GRID_ORDER_INCREMENT_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_ORDER_INCREMENT_ID" indexType="btree"> <column name="order_increment_id"/> </index> - <index name="SALES_CREDITMEMO_GRID_CREATED_AT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_CREDITMEMO_GRID_UPDATED_AT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_UPDATED_AT" indexType="btree"> <column name="updated_at"/> </index> - <index name="SALES_CREDITMEMO_GRID_ORDER_CREATED_AT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_ORDER_CREATED_AT" indexType="btree"> <column name="order_created_at"/> </index> - <index name="SALES_CREDITMEMO_GRID_STATE" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_STATE" indexType="btree"> <column name="state"/> </index> - <index name="SALES_CREDITMEMO_GRID_BILLING_NAME" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_BILLING_NAME" indexType="btree"> <column name="billing_name"/> </index> - <index name="SALES_CREDITMEMO_GRID_ORDER_STATUS" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_ORDER_STATUS" indexType="btree"> <column name="order_status"/> </index> - <index name="SALES_CREDITMEMO_GRID_BASE_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_BASE_GRAND_TOTAL" indexType="btree"> <column name="base_grand_total"/> </index> - <index name="SALES_CREDITMEMO_GRID_STORE_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_CREDITMEMO_GRID_ORDER_BASE_GRAND_TOTAL" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_ORDER_BASE_GRAND_TOTAL" indexType="btree"> <column name="order_base_grand_total"/> </index> - <index name="SALES_CREDITMEMO_GRID_ORDER_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_GRID_ORDER_ID" indexType="btree"> <column name="order_id"/> </index> - <index name="FTI_32B7BA885941A8254EE84AE650ABDC86" indexType="fulltext"> + <index referenceId="FTI_32B7BA885941A8254EE84AE650ABDC86" indexType="fulltext"> <column name="increment_id"/> <column name="order_increment_id"/> <column name="billing_name"/> @@ -1482,13 +1482,13 @@ unsigned="false" nullable="true" comment="Base Discount Tax Compensation Amount"/> <column xsi:type="text" name="tax_ratio" nullable="true" comment="Ratio of tax in the creditmemo item over tax of the order item"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_CREDITMEMO_ITEM_PARENT_ID_SALES_CREDITMEMO_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_CREDITMEMO_ITEM_PARENT_ID_SALES_CREDITMEMO_ENTITY_ID" table="sales_creditmemo_item" column="parent_id" referenceTable="sales_creditmemo" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_CREDITMEMO_ITEM_PARENT_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_ITEM_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -1504,16 +1504,16 @@ <column xsi:type="text" name="comment" nullable="true" comment="Comment"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Created At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_CREDITMEMO_COMMENT_PARENT_ID_SALES_CREDITMEMO_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_CREDITMEMO_COMMENT_PARENT_ID_SALES_CREDITMEMO_ENTITY_ID" table="sales_creditmemo_comment" column="parent_id" referenceTable="sales_creditmemo" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALES_CREDITMEMO_COMMENT_CREATED_AT" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_COMMENT_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> - <index name="SALES_CREDITMEMO_COMMENT_PARENT_ID" indexType="btree"> + <index referenceId="SALES_CREDITMEMO_COMMENT_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> </table> @@ -1533,18 +1533,18 @@ comment="Invoiced Captured"/> <column xsi:type="decimal" name="invoiced_not_captured" scale="4" precision="12" unsigned="false" nullable="true" comment="Invoiced Not Captured"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_INVOICED_AGGREGATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_INVOICED_AGGREGATED_STORE_ID_STORE_STORE_ID" table="sales_invoiced_aggregated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_INVOICED_AGGREGATED_PERIOD_STORE_ID_ORDER_STATUS"> + <constraint xsi:type="unique" referenceId="SALES_INVOICED_AGGREGATED_PERIOD_STORE_ID_ORDER_STATUS"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> </constraint> - <index name="SALES_INVOICED_AGGREGATED_STORE_ID" indexType="btree"> + <index referenceId="SALES_INVOICED_AGGREGATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1565,18 +1565,18 @@ comment="Invoiced Captured"/> <column xsi:type="decimal" name="invoiced_not_captured" scale="4" precision="12" unsigned="false" nullable="true" comment="Invoiced Not Captured"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_INVOICED_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_INVOICED_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" table="sales_invoiced_aggregated_order" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_INVOICED_AGGREGATED_ORDER_PERIOD_STORE_ID_ORDER_STATUS"> + <constraint xsi:type="unique" referenceId="SALES_INVOICED_AGGREGATED_ORDER_PERIOD_STORE_ID_ORDER_STATUS"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> </constraint> - <index name="SALES_INVOICED_AGGREGATED_ORDER_STORE_ID" indexType="btree"> + <index referenceId="SALES_INVOICED_AGGREGATED_ORDER_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1619,18 +1619,18 @@ nullable="false" default="0" comment="Total Discount Amount"/> <column xsi:type="decimal" name="total_discount_amount_actual" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Total Discount Amount Actual"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_AGGREGATED_CREATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_AGGREGATED_CREATED_STORE_ID_STORE_STORE_ID" table="sales_order_aggregated_created" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_ORDER_AGGREGATED_CREATED_PERIOD_STORE_ID_ORDER_STATUS"> + <constraint xsi:type="unique" referenceId="SALES_ORDER_AGGREGATED_CREATED_PERIOD_STORE_ID_ORDER_STATUS"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> </constraint> - <index name="SALES_ORDER_AGGREGATED_CREATED_STORE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_AGGREGATED_CREATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1673,18 +1673,18 @@ nullable="false" default="0" comment="Total Discount Amount"/> <column xsi:type="decimal" name="total_discount_amount_actual" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Total Discount Amount Actual"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_AGGREGATED_UPDATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_AGGREGATED_UPDATED_STORE_ID_STORE_STORE_ID" table="sales_order_aggregated_updated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_ORDER_AGGREGATED_UPDATED_PERIOD_STORE_ID_ORDER_STATUS"> + <constraint xsi:type="unique" referenceId="SALES_ORDER_AGGREGATED_UPDATED_PERIOD_STORE_ID_ORDER_STATUS"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> </constraint> - <index name="SALES_ORDER_AGGREGATED_UPDATED_STORE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_AGGREGATED_UPDATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1705,27 +1705,27 @@ <column xsi:type="blob" name="additional_information" nullable="true" comment="Additional Information"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Created At"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="transaction_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_PAYMENT_TRANSACTION_ORDER_ID_SALES_ORDER_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALES_PAYMENT_TRANSACTION_ORDER_ID_SALES_ORDER_ENTITY_ID" table="sales_payment_transaction" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_B99FF1A06402D725EBDB0F3A7ECD47A2" table="sales_payment_transaction" + <constraint xsi:type="foreign" referenceId="FK_B99FF1A06402D725EBDB0F3A7ECD47A2" table="sales_payment_transaction" column="parent_id" referenceTable="sales_payment_transaction" referenceColumn="transaction_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_PAYMENT_TRANSACTION_PAYMENT_ID_SALES_ORDER_PAYMENT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="SALES_PAYMENT_TRANSACTION_PAYMENT_ID_SALES_ORDER_PAYMENT_ENTT_ID" table="sales_payment_transaction" column="payment_id" referenceTable="sales_order_payment" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALES_PAYMENT_TRANSACTION_ORDER_ID_PAYMENT_ID_TXN_ID"> + <constraint xsi:type="unique" referenceId="SALES_PAYMENT_TRANSACTION_ORDER_ID_PAYMENT_ID_TXN_ID"> <column name="order_id"/> <column name="payment_id"/> <column name="txn_id"/> </constraint> - <index name="SALES_PAYMENT_TRANSACTION_PARENT_ID" indexType="btree"> + <index referenceId="SALES_PAYMENT_TRANSACTION_PARENT_ID" indexType="btree"> <column name="parent_id"/> </index> - <index name="SALES_PAYMENT_TRANSACTION_PAYMENT_ID" indexType="btree"> + <index referenceId="SALES_PAYMENT_TRANSACTION_PAYMENT_ID" indexType="btree"> <column name="payment_id"/> </index> </table> @@ -1743,18 +1743,18 @@ comment="Online Refunded"/> <column xsi:type="decimal" name="offline_refunded" scale="4" precision="12" unsigned="false" nullable="true" comment="Offline Refunded"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_REFUNDED_AGGREGATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_REFUNDED_AGGREGATED_STORE_ID_STORE_STORE_ID" table="sales_refunded_aggregated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_REFUNDED_AGGREGATED_PERIOD_STORE_ID_ORDER_STATUS"> + <constraint xsi:type="unique" referenceId="SALES_REFUNDED_AGGREGATED_PERIOD_STORE_ID_ORDER_STATUS"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> </constraint> - <index name="SALES_REFUNDED_AGGREGATED_STORE_ID" indexType="btree"> + <index referenceId="SALES_REFUNDED_AGGREGATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1773,18 +1773,18 @@ comment="Online Refunded"/> <column xsi:type="decimal" name="offline_refunded" scale="4" precision="12" unsigned="false" nullable="true" comment="Offline Refunded"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_REFUNDED_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_REFUNDED_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" table="sales_refunded_aggregated_order" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_REFUNDED_AGGREGATED_ORDER_PERIOD_STORE_ID_ORDER_STATUS"> + <constraint xsi:type="unique" referenceId="SALES_REFUNDED_AGGREGATED_ORDER_PERIOD_STORE_ID_ORDER_STATUS"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> </constraint> - <index name="SALES_REFUNDED_AGGREGATED_ORDER_STORE_ID" indexType="btree"> + <index referenceId="SALES_REFUNDED_AGGREGATED_ORDER_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1802,19 +1802,19 @@ comment="Total Shipping"/> <column xsi:type="decimal" name="total_shipping_actual" scale="4" precision="12" unsigned="false" nullable="true" comment="Total Shipping Actual"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SHIPPING_AGGREGATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_SHIPPING_AGGREGATED_STORE_ID_STORE_STORE_ID" table="sales_shipping_aggregated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SALES_SHPP_AGGRED_PERIOD_STORE_ID_ORDER_STS_SHPP_DESCRIPTION"> + <constraint xsi:type="unique" referenceId="SALES_SHPP_AGGRED_PERIOD_STORE_ID_ORDER_STS_SHPP_DESCRIPTION"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> <column name="shipping_description"/> </constraint> - <index name="SALES_SHIPPING_AGGREGATED_STORE_ID" indexType="btree"> + <index referenceId="SALES_SHIPPING_AGGREGATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1833,19 +1833,19 @@ comment="Total Shipping"/> <column xsi:type="decimal" name="total_shipping_actual" scale="4" precision="12" unsigned="false" nullable="true" comment="Total Shipping Actual"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SHIPPING_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_SHIPPING_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" table="sales_shipping_aggregated_order" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="UNQ_C05FAE47282EEA68654D0924E946761F"> + <constraint xsi:type="unique" referenceId="UNQ_C05FAE47282EEA68654D0924E946761F"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> <column name="shipping_description"/> </constraint> - <index name="SALES_SHIPPING_AGGREGATED_ORDER_STORE_ID" indexType="btree"> + <index referenceId="SALES_SHIPPING_AGGREGATED_ORDER_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -1864,21 +1864,21 @@ default="0" comment="Qty Ordered"/> <column xsi:type="smallint" name="rating_pos" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Rating Pos"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_BESTSELLERS_AGGREGATED_DAILY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_BESTSELLERS_AGGREGATED_DAILY_STORE_ID_STORE_STORE_ID" table="sales_bestsellers_aggregated_daily" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALES_BESTSELLERS_AGGREGATED_DAILY_PERIOD_STORE_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="SALES_BESTSELLERS_AGGREGATED_DAILY_PERIOD_STORE_ID_PRODUCT_ID"> <column name="period"/> <column name="store_id"/> <column name="product_id"/> </constraint> - <index name="SALES_BESTSELLERS_AGGREGATED_DAILY_STORE_ID" indexType="btree"> + <index referenceId="SALES_BESTSELLERS_AGGREGATED_DAILY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_BESTSELLERS_AGGREGATED_DAILY_PRODUCT_ID" indexType="btree"> + <index referenceId="SALES_BESTSELLERS_AGGREGATED_DAILY_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -1897,21 +1897,21 @@ default="0" comment="Qty Ordered"/> <column xsi:type="smallint" name="rating_pos" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Rating Pos"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_BESTSELLERS_AGGREGATED_MONTHLY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_BESTSELLERS_AGGREGATED_MONTHLY_STORE_ID_STORE_STORE_ID" table="sales_bestsellers_aggregated_monthly" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALES_BESTSELLERS_AGGREGATED_MONTHLY_PERIOD_STORE_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="SALES_BESTSELLERS_AGGREGATED_MONTHLY_PERIOD_STORE_ID_PRODUCT_ID"> <column name="period"/> <column name="store_id"/> <column name="product_id"/> </constraint> - <index name="SALES_BESTSELLERS_AGGREGATED_MONTHLY_STORE_ID" indexType="btree"> + <index referenceId="SALES_BESTSELLERS_AGGREGATED_MONTHLY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_BESTSELLERS_AGGREGATED_MONTHLY_PRODUCT_ID" indexType="btree"> + <index referenceId="SALES_BESTSELLERS_AGGREGATED_MONTHLY_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -1930,21 +1930,21 @@ default="0" comment="Qty Ordered"/> <column xsi:type="smallint" name="rating_pos" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Rating Pos"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_BESTSELLERS_AGGREGATED_YEARLY_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_BESTSELLERS_AGGREGATED_YEARLY_STORE_ID_STORE_STORE_ID" table="sales_bestsellers_aggregated_yearly" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALES_BESTSELLERS_AGGREGATED_YEARLY_PERIOD_STORE_ID_PRODUCT_ID"> + <constraint xsi:type="unique" referenceId="SALES_BESTSELLERS_AGGREGATED_YEARLY_PERIOD_STORE_ID_PRODUCT_ID"> <column name="period"/> <column name="store_id"/> <column name="product_id"/> </constraint> - <index name="SALES_BESTSELLERS_AGGREGATED_YEARLY_STORE_ID" indexType="btree"> + <index referenceId="SALES_BESTSELLERS_AGGREGATED_YEARLY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALES_BESTSELLERS_AGGREGATED_YEARLY_PRODUCT_ID" indexType="btree"> + <index referenceId="SALES_BESTSELLERS_AGGREGATED_YEARLY_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> </table> @@ -1969,10 +1969,10 @@ comment="Process"/> <column xsi:type="decimal" name="base_real_amount" scale="4" precision="12" unsigned="false" nullable="true" comment="Base Real Amount"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="tax_id"/> </constraint> - <index name="SALES_ORDER_TAX_ORDER_ID_PRIORITY_POSITION" indexType="btree"> + <index referenceId="SALES_ORDER_TAX_ORDER_ID_PRIORITY_POSITION" indexType="btree"> <column name="order_id"/> <column name="priority"/> <column name="position"/> @@ -1999,30 +1999,30 @@ comment="Id of the associated item"/> <column xsi:type="varchar" name="taxable_item_type" nullable="false" length="32" comment="Type of the taxable item"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="tax_item_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_TAX_ITEM_ASSOCIATED_ITEM_ID_SALES_ORDER_ITEM_ITEM_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_TAX_ITEM_ASSOCIATED_ITEM_ID_SALES_ORDER_ITEM_ITEM_ID" table="sales_order_tax_item" column="associated_item_id" referenceTable="sales_order_item" referenceColumn="item_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_ORDER_TAX_ITEM_TAX_ID_SALES_ORDER_TAX_TAX_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_TAX_ITEM_TAX_ID_SALES_ORDER_TAX_TAX_ID" table="sales_order_tax_item" column="tax_id" referenceTable="sales_order_tax" referenceColumn="tax_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_ORDER_TAX_ITEM_ITEM_ID_SALES_ORDER_ITEM_ITEM_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_TAX_ITEM_ITEM_ID_SALES_ORDER_ITEM_ITEM_ID" table="sales_order_tax_item" column="item_id" referenceTable="sales_order_item" referenceColumn="item_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALES_ORDER_TAX_ITEM_TAX_ID_ITEM_ID"> + <constraint xsi:type="unique" referenceId="SALES_ORDER_TAX_ITEM_TAX_ID_ITEM_ID"> <column name="tax_id"/> <column name="item_id"/> </constraint> - <index name="SALES_ORDER_TAX_ITEM_ITEM_ID" indexType="btree"> + <index referenceId="SALES_ORDER_TAX_ITEM_ITEM_ID" indexType="btree"> <column name="item_id"/> </index> </table> <table name="sales_order_status" resource="sales" engine="innodb" comment="Sales Order Status Table"> <column xsi:type="varchar" name="status" nullable="false" length="32" comment="Status"/> <column xsi:type="varchar" name="label" nullable="false" length="128" comment="Label"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="status"/> </constraint> </table> @@ -2033,11 +2033,11 @@ default="0" comment="Is Default"/> <column xsi:type="smallint" name="visible_on_front" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Visible on front"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="status"/> <column name="state"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_STATUS_STATE_STATUS_SALES_ORDER_STATUS_STATUS" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_STATUS_STATE_STATUS_SALES_ORDER_STATUS_STATUS" table="sales_order_status_state" column="status" referenceTable="sales_order_status" referenceColumn="status" onDelete="CASCADE"/> </table> @@ -2046,17 +2046,17 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> <column xsi:type="varchar" name="label" nullable="false" length="128" comment="Label"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="status"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_ORDER_STATUS_LABEL_STATUS_SALES_ORDER_STATUS_STATUS" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_STATUS_LABEL_STATUS_SALES_ORDER_STATUS_STATUS" table="sales_order_status_label" column="status" referenceTable="sales_order_status" referenceColumn="status" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALES_ORDER_STATUS_LABEL_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALES_ORDER_STATUS_LABEL_STORE_ID_STORE_STORE_ID" table="sales_order_status_label" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="SALES_ORDER_STATUS_LABEL_STORE_ID" indexType="btree"> + <index referenceId="SALES_ORDER_STATUS_LABEL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/SalesRule/etc/db_schema.xml b/app/code/Magento/SalesRule/etc/db_schema.xml index cdbd50c3f3472..9c220d36d387a 100644 --- a/app/code/Magento/SalesRule/etc/db_schema.xml +++ b/app/code/Magento/SalesRule/etc/db_schema.xml @@ -46,10 +46,10 @@ identity="false" default="0" comment="Use Auto Generation"/> <column xsi:type="int" name="uses_per_coupon" padding="11" unsigned="false" nullable="false" identity="false" default="0" comment="User Per Coupon"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> </constraint> - <index name="SALESRULE_IS_ACTIVE_SORT_ORDER_TO_DATE_FROM_DATE" indexType="btree"> + <index referenceId="SALESRULE_IS_ACTIVE_SORT_ORDER_TO_DATE_FROM_DATE" indexType="btree"> <column name="is_active"/> <column name="sort_order"/> <column name="to_date"/> @@ -76,19 +76,19 @@ comment="Coupon Code Creation Date"/> <column xsi:type="smallint" name="type" padding="6" unsigned="false" nullable="true" identity="false" default="0" comment="Coupon Code Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="coupon_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_COUPON_RULE_ID_SALESRULE_RULE_ID" table="salesrule_coupon" + <constraint xsi:type="foreign" referenceId="SALESRULE_COUPON_RULE_ID_SALESRULE_RULE_ID" table="salesrule_coupon" column="rule_id" referenceTable="salesrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALESRULE_COUPON_CODE"> + <constraint xsi:type="unique" referenceId="SALESRULE_COUPON_CODE"> <column name="code"/> </constraint> - <constraint xsi:type="unique" name="SALESRULE_COUPON_RULE_ID_IS_PRIMARY"> + <constraint xsi:type="unique" referenceId="SALESRULE_COUPON_RULE_ID_IS_PRIMARY"> <column name="rule_id"/> <column name="is_primary"/> </constraint> - <index name="SALESRULE_COUPON_RULE_ID" indexType="btree"> + <index referenceId="SALESRULE_COUPON_RULE_ID" indexType="btree"> <column name="rule_id"/> </index> </table> @@ -99,17 +99,17 @@ comment="Customer Id"/> <column xsi:type="int" name="times_used" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Times Used"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="coupon_id"/> <column name="customer_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_COUPON_USAGE_COUPON_ID_SALESRULE_COUPON_COUPON_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_COUPON_USAGE_COUPON_ID_SALESRULE_COUPON_COUPON_ID" table="salesrule_coupon_usage" column="coupon_id" referenceTable="salesrule_coupon" referenceColumn="coupon_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_COUPON_USAGE_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_COUPON_USAGE_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="salesrule_coupon_usage" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <index name="SALESRULE_COUPON_USAGE_CUSTOMER_ID" indexType="btree"> + <index referenceId="SALESRULE_COUPON_USAGE_CUSTOMER_ID" indexType="btree"> <column name="customer_id"/> </index> </table> @@ -122,19 +122,19 @@ default="0" comment="Customer Id"/> <column xsi:type="smallint" name="times_used" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Times Used"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_customer_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_CUSTOMER_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_CUSTOMER_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="salesrule_customer" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_CUSTOMER_RULE_ID_SALESRULE_RULE_ID" table="salesrule_customer" + <constraint xsi:type="foreign" referenceId="SALESRULE_CUSTOMER_RULE_ID_SALESRULE_RULE_ID" table="salesrule_customer" column="rule_id" referenceTable="salesrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <index name="SALESRULE_CUSTOMER_RULE_ID_CUSTOMER_ID" indexType="btree"> + <index referenceId="SALESRULE_CUSTOMER_RULE_ID_CUSTOMER_ID" indexType="btree"> <column name="rule_id"/> <column name="customer_id"/> </index> - <index name="SALESRULE_CUSTOMER_CUSTOMER_ID_RULE_ID" indexType="btree"> + <index referenceId="SALESRULE_CUSTOMER_CUSTOMER_ID_RULE_ID" indexType="btree"> <column name="customer_id"/> <column name="rule_id"/> </index> @@ -147,18 +147,18 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> <column xsi:type="varchar" name="label" nullable="true" length="255" comment="Label"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="label_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_LABEL_RULE_ID_SALESRULE_RULE_ID" table="salesrule_label" + <constraint xsi:type="foreign" referenceId="SALESRULE_LABEL_RULE_ID_SALESRULE_RULE_ID" table="salesrule_label" column="rule_id" referenceTable="salesrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_LABEL_STORE_ID_STORE_STORE_ID" table="salesrule_label" + <constraint xsi:type="foreign" referenceId="SALESRULE_LABEL_STORE_ID_STORE_STORE_ID" table="salesrule_label" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALESRULE_LABEL_RULE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALESRULE_LABEL_RULE_ID_STORE_ID"> <column name="rule_id"/> <column name="store_id"/> </constraint> - <index name="SALESRULE_LABEL_STORE_ID" indexType="btree"> + <index referenceId="SALESRULE_LABEL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -170,31 +170,31 @@ comment="Customer Group Id"/> <column xsi:type="smallint" name="attribute_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Attribute Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="website_id"/> <column name="customer_group_id"/> <column name="attribute_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_PRD_ATTR_ATTR_ID_EAV_ATTR_ATTR_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_PRD_ATTR_ATTR_ID_EAV_ATTR_ATTR_ID" table="salesrule_product_attribute" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_PRD_ATTR_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_PRD_ATTR_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" table="salesrule_product_attribute" column="customer_group_id" referenceTable="customer_group" referenceColumn="customer_group_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_PRODUCT_ATTRIBUTE_RULE_ID_SALESRULE_RULE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_PRODUCT_ATTRIBUTE_RULE_ID_SALESRULE_RULE_ID" table="salesrule_product_attribute" column="rule_id" referenceTable="salesrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_PRODUCT_ATTRIBUTE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_PRODUCT_ATTRIBUTE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="salesrule_product_attribute" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="SALESRULE_PRODUCT_ATTRIBUTE_WEBSITE_ID" indexType="btree"> + <index referenceId="SALESRULE_PRODUCT_ATTRIBUTE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="SALESRULE_PRODUCT_ATTRIBUTE_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="SALESRULE_PRODUCT_ATTRIBUTE_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index name="SALESRULE_PRODUCT_ATTRIBUTE_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="SALESRULE_PRODUCT_ATTRIBUTE_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> @@ -220,22 +220,22 @@ <column xsi:type="decimal" name="total_amount_actual" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Total Amount Actual"/> <column xsi:type="varchar" name="rule_name" nullable="true" length="255" comment="Rule Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_COUPON_AGGREGATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_COUPON_AGGREGATED_STORE_ID_STORE_STORE_ID" table="salesrule_coupon_aggregated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALESRULE_COUPON_AGGRED_PERIOD_STORE_ID_ORDER_STS_COUPON_CODE"> + <constraint xsi:type="unique" referenceId="SALESRULE_COUPON_AGGRED_PERIOD_STORE_ID_ORDER_STS_COUPON_CODE"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> <column name="coupon_code"/> </constraint> - <index name="SALESRULE_COUPON_AGGREGATED_STORE_ID" indexType="btree"> + <index referenceId="SALESRULE_COUPON_AGGREGATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALESRULE_COUPON_AGGREGATED_RULE_NAME" indexType="btree"> + <index referenceId="SALESRULE_COUPON_AGGREGATED_RULE_NAME" indexType="btree"> <column name="rule_name"/> </index> </table> @@ -262,22 +262,22 @@ <column xsi:type="decimal" name="total_amount_actual" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Total Amount Actual"/> <column xsi:type="varchar" name="rule_name" nullable="true" length="255" comment="Rule Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_COUPON_AGGREGATED_UPDATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_COUPON_AGGREGATED_UPDATED_STORE_ID_STORE_STORE_ID" table="salesrule_coupon_aggregated_updated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="UNQ_7196FA120A4F0F84E1B66605E87E213E"> + <constraint xsi:type="unique" referenceId="UNQ_7196FA120A4F0F84E1B66605E87E213E"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> <column name="coupon_code"/> </constraint> - <index name="SALESRULE_COUPON_AGGREGATED_UPDATED_STORE_ID" indexType="btree"> + <index referenceId="SALESRULE_COUPON_AGGREGATED_UPDATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALESRULE_COUPON_AGGREGATED_UPDATED_RULE_NAME" indexType="btree"> + <index referenceId="SALESRULE_COUPON_AGGREGATED_UPDATED_RULE_NAME" indexType="btree"> <column name="rule_name"/> </index> </table> @@ -298,22 +298,22 @@ <column xsi:type="decimal" name="total_amount" scale="4" precision="12" unsigned="false" nullable="false" default="0" comment="Total Amount"/> <column xsi:type="varchar" name="rule_name" nullable="true" length="255" comment="Rule Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_COUPON_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_COUPON_AGGREGATED_ORDER_STORE_ID_STORE_STORE_ID" table="salesrule_coupon_aggregated_order" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="UNQ_1094D1FBBCBB11704A29DEF3ACC37D2B"> + <constraint xsi:type="unique" referenceId="UNQ_1094D1FBBCBB11704A29DEF3ACC37D2B"> <column name="period"/> <column name="store_id"/> <column name="order_status"/> <column name="coupon_code"/> </constraint> - <index name="SALESRULE_COUPON_AGGREGATED_ORDER_STORE_ID" indexType="btree"> + <index referenceId="SALESRULE_COUPON_AGGREGATED_ORDER_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SALESRULE_COUPON_AGGREGATED_ORDER_RULE_NAME" indexType="btree"> + <index referenceId="SALESRULE_COUPON_AGGREGATED_ORDER_RULE_NAME" indexType="btree"> <column name="rule_name"/> </index> </table> @@ -321,16 +321,16 @@ <column xsi:type="int" name="rule_id" padding="10" unsigned="true" nullable="false" identity="false"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Website Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="website_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_WEBSITE_RULE_ID_SALESRULE_RULE_ID" table="salesrule_website" + <constraint xsi:type="foreign" referenceId="SALESRULE_WEBSITE_RULE_ID_SALESRULE_RULE_ID" table="salesrule_website" column="rule_id" referenceTable="salesrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_WEBSITE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_WEBSITE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="salesrule_website" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="SALESRULE_WEBSITE_WEBSITE_ID" indexType="btree"> + <index referenceId="SALESRULE_WEBSITE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> @@ -339,17 +339,17 @@ <column xsi:type="int" name="rule_id" padding="10" unsigned="true" nullable="false" identity="false"/> <column xsi:type="int" name="customer_group_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Customer Group Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="rule_id"/> <column name="customer_group_id"/> </constraint> - <constraint xsi:type="foreign" name="SALESRULE_CUSTOMER_GROUP_RULE_ID_SALESRULE_RULE_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_CUSTOMER_GROUP_RULE_ID_SALESRULE_RULE_ID" table="salesrule_customer_group" column="rule_id" referenceTable="salesrule" referenceColumn="rule_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SALESRULE_CSTR_GROUP_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" + <constraint xsi:type="foreign" referenceId="SALESRULE_CSTR_GROUP_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID" table="salesrule_customer_group" column="customer_group_id" referenceTable="customer_group" referenceColumn="customer_group_id" onDelete="CASCADE"/> - <index name="SALESRULE_CUSTOMER_GROUP_CUSTOMER_GROUP_ID" indexType="btree"> + <index referenceId="SALESRULE_CUSTOMER_GROUP_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> </table> diff --git a/app/code/Magento/SalesSequence/etc/db_schema.xml b/app/code/Magento/SalesSequence/etc/db_schema.xml index 530a9a33b0cfe..0e580b85bd608 100644 --- a/app/code/Magento/SalesSequence/etc/db_schema.xml +++ b/app/code/Magento/SalesSequence/etc/db_schema.xml @@ -23,13 +23,13 @@ <column xsi:type="int" name="warning_value" padding="10" unsigned="true" nullable="false" identity="false" comment="WarningValue for sequence"/> <column xsi:type="boolean" name="is_active" nullable="false" default="false" comment="isActive flag"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="profile_id"/> </constraint> - <constraint xsi:type="foreign" name="SALES_SEQUENCE_PROFILE_META_ID_SALES_SEQUENCE_META_META_ID" + <constraint xsi:type="foreign" referenceId="SALES_SEQUENCE_PROFILE_META_ID_SALES_SEQUENCE_META_META_ID" table="sales_sequence_profile" column="meta_id" referenceTable="sales_sequence_meta" referenceColumn="meta_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SALES_SEQUENCE_PROFILE_META_ID_PREFIX_SUFFIX"> + <constraint xsi:type="unique" referenceId="SALES_SEQUENCE_PROFILE_META_ID_PREFIX_SUFFIX"> <column name="meta_id"/> <column name="prefix"/> <column name="suffix"/> @@ -42,10 +42,10 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> <column xsi:type="varchar" name="sequence_table" nullable="false" length="32" comment="table for sequence"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="meta_id"/> </constraint> - <constraint xsi:type="unique" name="SALES_SEQUENCE_META_ENTITY_TYPE_STORE_ID"> + <constraint xsi:type="unique" referenceId="SALES_SEQUENCE_META_ENTITY_TYPE_STORE_ID"> <column name="entity_type"/> <column name="store_id"/> </constraint> diff --git a/app/code/Magento/Search/etc/db_schema.xml b/app/code/Magento/Search/etc/db_schema.xml index 9b2dfb493dbb8..754af7d246d6d 100644 --- a/app/code/Magento/Search/etc/db_schema.xml +++ b/app/code/Magento/Search/etc/db_schema.xml @@ -26,24 +26,24 @@ default="0" comment="Processed status"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Updated at"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="query_id"/> </constraint> - <constraint xsi:type="foreign" name="SEARCH_QUERY_STORE_ID_STORE_STORE_ID" table="search_query" + <constraint xsi:type="foreign" referenceId="SEARCH_QUERY_STORE_ID_STORE_STORE_ID" table="search_query" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="SEARCH_QUERY_QUERY_TEXT_STORE_ID"> + <constraint xsi:type="unique" referenceId="SEARCH_QUERY_QUERY_TEXT_STORE_ID"> <column name="query_text"/> <column name="store_id"/> </constraint> - <index name="SEARCH_QUERY_QUERY_TEXT_STORE_ID_POPULARITY" indexType="btree"> + <index referenceId="SEARCH_QUERY_QUERY_TEXT_STORE_ID_POPULARITY" indexType="btree"> <column name="query_text"/> <column name="store_id"/> <column name="popularity"/> </index> - <index name="SEARCH_QUERY_STORE_ID" indexType="btree"> + <index referenceId="SEARCH_QUERY_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SEARCH_QUERY_IS_PROCESSED" indexType="btree"> + <index referenceId="SEARCH_QUERY_IS_PROCESSED" indexType="btree"> <column name="is_processed"/> </index> </table> @@ -55,21 +55,21 @@ default="0" comment="Store Id - identifies the store view these synonyms belong to"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website Id - identifies the website id these synonyms belong to"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="group_id"/> </constraint> - <constraint xsi:type="foreign" name="SEARCH_SYNONYMS_STORE_ID_STORE_STORE_ID" table="search_synonyms" + <constraint xsi:type="foreign" referenceId="SEARCH_SYNONYMS_STORE_ID_STORE_STORE_ID" table="search_synonyms" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="SEARCH_SYNONYMS_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" + <constraint xsi:type="foreign" referenceId="SEARCH_SYNONYMS_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="search_synonyms" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <index name="SEARCH_SYNONYMS_SYNONYMS" indexType="fulltext"> + <index referenceId="SEARCH_SYNONYMS_SYNONYMS" indexType="fulltext"> <column name="synonyms"/> </index> - <index name="SEARCH_SYNONYMS_STORE_ID" indexType="btree"> + <index referenceId="SEARCH_SYNONYMS_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index name="SEARCH_SYNONYMS_WEBSITE_ID" indexType="btree"> + <index referenceId="SEARCH_SYNONYMS_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> diff --git a/app/code/Magento/Security/etc/db_schema.xml b/app/code/Magento/Security/etc/db_schema.xml index f14e6de79e894..ce7143582ce69 100644 --- a/app/code/Magento/Security/etc/db_schema.xml +++ b/app/code/Magento/Security/etc/db_schema.xml @@ -21,15 +21,15 @@ comment="Update Time"/> <column xsi:type="varchar" name="ip" nullable="false" length="15" onCreate="migrateDataFrom(ip)" comment="Remote user IP"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="ADMIN_USER_SESSION_USER_ID_ADMIN_USER_USER_ID" table="admin_user_session" + <constraint xsi:type="foreign" referenceId="ADMIN_USER_SESSION_USER_ID_ADMIN_USER_USER_ID" table="admin_user_session" column="user_id" referenceTable="admin_user" referenceColumn="user_id" onDelete="CASCADE"/> - <index name="ADMIN_USER_SESSION_SESSION_ID" indexType="btree"> + <index referenceId="ADMIN_USER_SESSION_SESSION_ID" indexType="btree"> <column name="session_id"/> </index> - <index name="ADMIN_USER_SESSION_USER_ID" indexType="btree"> + <index referenceId="ADMIN_USER_SESSION_USER_ID" indexType="btree"> <column name="user_id"/> </index> </table> @@ -45,13 +45,13 @@ comment="Timestamp when the event occurs"/> <column xsi:type="varchar" name="ip" nullable="false" length="15" onCreate="migrateDataFrom(ip)" comment="Remote user IP"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <index name="PASSWORD_RESET_REQUEST_EVENT_ACCOUNT_REFERENCE" indexType="btree"> + <index referenceId="PASSWORD_RESET_REQUEST_EVENT_ACCOUNT_REFERENCE" indexType="btree"> <column name="account_reference"/> </index> - <index name="PASSWORD_RESET_REQUEST_EVENT_CREATED_AT" indexType="btree"> + <index referenceId="PASSWORD_RESET_REQUEST_EVENT_CREATED_AT" indexType="btree"> <column name="created_at"/> </index> </table> diff --git a/app/code/Magento/SendFriend/etc/db_schema.xml b/app/code/Magento/SendFriend/etc/db_schema.xml index 7537f67cf552a..b9551749dfc6d 100644 --- a/app/code/Magento/SendFriend/etc/db_schema.xml +++ b/app/code/Magento/SendFriend/etc/db_schema.xml @@ -16,13 +16,13 @@ comment="Log time"/> <column xsi:type="smallint" name="website_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Website ID"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="log_id"/> </constraint> - <index name="SENDFRIEND_LOG_IP" indexType="btree"> + <index referenceId="SENDFRIEND_LOG_IP" indexType="btree"> <column name="ip"/> </index> - <index name="SENDFRIEND_LOG_TIME" indexType="btree"> + <index referenceId="SENDFRIEND_LOG_TIME" indexType="btree"> <column name="time"/> </index> </table> diff --git a/app/code/Magento/Signifyd/etc/db_schema.xml b/app/code/Magento/Signifyd/etc/db_schema.xml index 6a31eacbb45f5..1cee590dec745 100644 --- a/app/code/Magento/Signifyd/etc/db_schema.xml +++ b/app/code/Magento/Signifyd/etc/db_schema.xml @@ -24,15 +24,15 @@ <column xsi:type="varchar" name="review_disposition" nullable="true" length="32" comment="Review_disposition"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="true" comment="Created_at"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="true" comment="Updated_at"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="SIGNIFYD_CASE_ORDER_ID_SALES_ORDER_ENTITY_ID" table="signifyd_case" + <constraint xsi:type="foreign" referenceId="SIGNIFYD_CASE_ORDER_ID_SALES_ORDER_ENTITY_ID" table="signifyd_case" column="order_id" referenceTable="sales_order" referenceColumn="entity_id" onDelete="SET NULL"/> - <constraint xsi:type="unique" name="SIGNIFYD_CASE_ORDER_ID"> + <constraint xsi:type="unique" referenceId="SIGNIFYD_CASE_ORDER_ID"> <column name="order_id"/> </constraint> - <constraint xsi:type="unique" name="SIGNIFYD_CASE_CASE_ID"> + <constraint xsi:type="unique" referenceId="SIGNIFYD_CASE_CASE_ID"> <column name="case_id"/> </constraint> </table> diff --git a/app/code/Magento/Sitemap/etc/db_schema.xml b/app/code/Magento/Sitemap/etc/db_schema.xml index 82a9b8ef5148c..b3c028b626b73 100644 --- a/app/code/Magento/Sitemap/etc/db_schema.xml +++ b/app/code/Magento/Sitemap/etc/db_schema.xml @@ -16,12 +16,12 @@ <column xsi:type="timestamp" name="sitemap_time" on_update="false" nullable="true" comment="Sitemap Time"/> <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="sitemap_id"/> </constraint> - <constraint xsi:type="foreign" name="SITEMAP_STORE_ID_STORE_STORE_ID" table="sitemap" column="store_id" + <constraint xsi:type="foreign" referenceId="SITEMAP_STORE_ID_STORE_STORE_ID" table="sitemap" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="SITEMAP_STORE_ID" indexType="btree"> + <index referenceId="SITEMAP_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/Store/etc/db_schema.xml b/app/code/Magento/Store/etc/db_schema.xml index 3c2bc3e3c117b..6eea94b8deec7 100644 --- a/app/code/Magento/Store/etc/db_schema.xml +++ b/app/code/Magento/Store/etc/db_schema.xml @@ -18,16 +18,16 @@ identity="false" default="0" comment="Default Group Id"/> <column xsi:type="smallint" name="is_default" padding="5" unsigned="true" nullable="true" identity="false" default="0" comment="Defines Is Website Default"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="website_id"/> </constraint> - <constraint xsi:type="unique" name="STORE_WEBSITE_CODE"> + <constraint xsi:type="unique" referenceId="STORE_WEBSITE_CODE"> <column name="code"/> </constraint> - <index name="STORE_WEBSITE_SORT_ORDER" indexType="btree"> + <index referenceId="STORE_WEBSITE_SORT_ORDER" indexType="btree"> <column name="sort_order"/> </index> - <index name="STORE_WEBSITE_DEFAULT_GROUP_ID" indexType="btree"> + <index referenceId="STORE_WEBSITE_DEFAULT_GROUP_ID" indexType="btree"> <column name="default_group_id"/> </index> </table> @@ -42,18 +42,18 @@ <column xsi:type="smallint" name="default_store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Default Store Id"/> <column xsi:type="varchar" name="code" nullable="true" length="32" comment="Store group unique code"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="group_id"/> </constraint> - <constraint xsi:type="foreign" name="STORE_GROUP_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="store_group" + <constraint xsi:type="foreign" referenceId="STORE_GROUP_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="store_group" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="STORE_GROUP_CODE"> + <constraint xsi:type="unique" referenceId="STORE_GROUP_CODE"> <column name="code"/> </constraint> - <index name="STORE_GROUP_WEBSITE_ID" indexType="btree"> + <index referenceId="STORE_GROUP_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="STORE_GROUP_DEFAULT_STORE_ID" indexType="btree"> + <index referenceId="STORE_GROUP_DEFAULT_STORE_ID" indexType="btree"> <column name="default_store_id"/> </index> </table> @@ -70,24 +70,24 @@ default="0" comment="Store Sort Order"/> <column xsi:type="smallint" name="is_active" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store Activity"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="STORE_GROUP_ID_STORE_GROUP_GROUP_ID" table="store" column="group_id" + <constraint xsi:type="foreign" referenceId="STORE_GROUP_ID_STORE_GROUP_GROUP_ID" table="store" column="group_id" referenceTable="store_group" referenceColumn="group_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="STORE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="store" + <constraint xsi:type="foreign" referenceId="STORE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="store" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="STORE_CODE"> + <constraint xsi:type="unique" referenceId="STORE_CODE"> <column name="code"/> </constraint> - <index name="STORE_WEBSITE_ID" indexType="btree"> + <index referenceId="STORE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="STORE_IS_ACTIVE_SORT_ORDER" indexType="btree"> + <index referenceId="STORE_IS_ACTIVE_SORT_ORDER" indexType="btree"> <column name="is_active"/> <column name="sort_order"/> </index> - <index name="STORE_GROUP_ID" indexType="btree"> + <index referenceId="STORE_GROUP_ID" indexType="btree"> <column name="group_id"/> </index> </table> diff --git a/app/code/Magento/Swatches/etc/db_schema.xml b/app/code/Magento/Swatches/etc/db_schema.xml index c960f27b0fb54..3dafbc3876494 100644 --- a/app/code/Magento/Swatches/etc/db_schema.xml +++ b/app/code/Magento/Swatches/etc/db_schema.xml @@ -20,20 +20,20 @@ <column xsi:type="smallint" name="type" padding="5" unsigned="true" nullable="false" identity="false" comment="Swatch type: 0 - text, 1 - visual color, 2 - visual image"/> <column xsi:type="varchar" name="value" nullable="true" length="255" comment="Swatch Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="swatch_id"/> </constraint> - <constraint xsi:type="foreign" name="EAV_ATTRIBUTE_OPTION_SWATCH_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_OPTION_SWATCH_STORE_ID_STORE_STORE_ID" table="eav_attribute_option_swatch" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="EAV_ATTR_OPT_SWATCH_OPT_ID_EAV_ATTR_OPT_OPT_ID" + <constraint xsi:type="foreign" referenceId="EAV_ATTR_OPT_SWATCH_OPT_ID_EAV_ATTR_OPT_OPT_ID" table="eav_attribute_option_swatch" column="option_id" referenceTable="eav_attribute_option" referenceColumn="option_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="EAV_ATTRIBUTE_OPTION_SWATCH_STORE_ID_OPTION_ID"> + <constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_OPTION_SWATCH_STORE_ID_OPTION_ID"> <column name="store_id"/> <column name="option_id"/> </constraint> - <index name="EAV_ATTRIBUTE_OPTION_SWATCH_SWATCH_ID" indexType="btree"> + <index referenceId="EAV_ATTRIBUTE_OPTION_SWATCH_SWATCH_ID" indexType="btree"> <column name="swatch_id"/> </index> </table> diff --git a/app/code/Magento/Tax/etc/db_schema.xml b/app/code/Magento/Tax/etc/db_schema.xml index 6e83a64791969..f5227a9ef3a66 100644 --- a/app/code/Magento/Tax/etc/db_schema.xml +++ b/app/code/Magento/Tax/etc/db_schema.xml @@ -13,7 +13,7 @@ <column xsi:type="varchar" name="class_name" nullable="false" length="255" comment="Class Name"/> <column xsi:type="varchar" name="class_type" nullable="false" length="8" default="CUSTOMER" comment="Class Type"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="class_id"/> </constraint> </table> @@ -27,14 +27,14 @@ comment="Position"/> <column xsi:type="int" name="calculate_subtotal" padding="11" unsigned="false" nullable="false" identity="false" comment="Calculate off subtotal option"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="tax_calculation_rule_id"/> </constraint> - <index name="TAX_CALCULATION_RULE_PRIORITY_POSITION" indexType="btree"> + <index referenceId="TAX_CALCULATION_RULE_PRIORITY_POSITION" indexType="btree"> <column name="priority"/> <column name="position"/> </index> - <index name="TAX_CALCULATION_RULE_CODE" indexType="btree"> + <index referenceId="TAX_CALCULATION_RULE_CODE" indexType="btree"> <column name="code"/> </index> </table> @@ -54,18 +54,18 @@ comment="Zip From"/> <column xsi:type="int" name="zip_to" padding="10" unsigned="true" nullable="true" identity="false" comment="Zip To"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="tax_calculation_rate_id"/> </constraint> - <index name="TAX_CALCULATION_RATE_TAX_COUNTRY_ID_TAX_REGION_ID_TAX_POSTCODE" indexType="btree"> + <index referenceId="TAX_CALCULATION_RATE_TAX_COUNTRY_ID_TAX_REGION_ID_TAX_POSTCODE" indexType="btree"> <column name="tax_country_id"/> <column name="tax_region_id"/> <column name="tax_postcode"/> </index> - <index name="TAX_CALCULATION_RATE_CODE" indexType="btree"> + <index referenceId="TAX_CALCULATION_RATE_CODE" indexType="btree"> <column name="code"/> </index> - <index name="IDX_CA799F1E2CB843495F601E56C84A626D" indexType="btree"> + <index referenceId="IDX_CA799F1E2CB843495F601E56C84A626D" indexType="btree"> <column name="tax_calculation_rate_id"/> <column name="tax_country_id"/> <column name="tax_region_id"/> @@ -84,31 +84,31 @@ identity="false" comment="Customer Tax Class Id"/> <column xsi:type="smallint" name="product_tax_class_id" padding="6" unsigned="false" nullable="false" identity="false" comment="Product Tax Class Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="tax_calculation_id"/> </constraint> - <constraint xsi:type="foreign" name="TAX_CALCULATION_PRODUCT_TAX_CLASS_ID_TAX_CLASS_CLASS_ID" + <constraint xsi:type="foreign" referenceId="TAX_CALCULATION_PRODUCT_TAX_CLASS_ID_TAX_CLASS_CLASS_ID" table="tax_calculation" column="product_tax_class_id" referenceTable="tax_class" referenceColumn="class_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="TAX_CALCULATION_CUSTOMER_TAX_CLASS_ID_TAX_CLASS_CLASS_ID" + <constraint xsi:type="foreign" referenceId="TAX_CALCULATION_CUSTOMER_TAX_CLASS_ID_TAX_CLASS_CLASS_ID" table="tax_calculation" column="customer_tax_class_id" referenceTable="tax_class" referenceColumn="class_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="TAX_CALC_TAX_CALC_RATE_ID_TAX_CALC_RATE_TAX_CALC_RATE_ID" + <constraint xsi:type="foreign" referenceId="TAX_CALC_TAX_CALC_RATE_ID_TAX_CALC_RATE_TAX_CALC_RATE_ID" table="tax_calculation" column="tax_calculation_rate_id" referenceTable="tax_calculation_rate" referenceColumn="tax_calculation_rate_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="TAX_CALC_TAX_CALC_RULE_ID_TAX_CALC_RULE_TAX_CALC_RULE_ID" + <constraint xsi:type="foreign" referenceId="TAX_CALC_TAX_CALC_RULE_ID_TAX_CALC_RULE_TAX_CALC_RULE_ID" table="tax_calculation" column="tax_calculation_rule_id" referenceTable="tax_calculation_rule" referenceColumn="tax_calculation_rule_id" onDelete="CASCADE"/> - <index name="TAX_CALCULATION_TAX_CALCULATION_RULE_ID" indexType="btree"> + <index referenceId="TAX_CALCULATION_TAX_CALCULATION_RULE_ID" indexType="btree"> <column name="tax_calculation_rule_id"/> </index> - <index name="TAX_CALCULATION_CUSTOMER_TAX_CLASS_ID" indexType="btree"> + <index referenceId="TAX_CALCULATION_CUSTOMER_TAX_CLASS_ID" indexType="btree"> <column name="customer_tax_class_id"/> </index> - <index name="TAX_CALCULATION_PRODUCT_TAX_CLASS_ID" indexType="btree"> + <index referenceId="TAX_CALCULATION_PRODUCT_TAX_CLASS_ID" indexType="btree"> <column name="product_tax_class_id"/> </index> - <index name="TAX_CALC_TAX_CALC_RATE_ID_CSTR_TAX_CLASS_ID_PRD_TAX_CLASS_ID" indexType="btree"> + <index referenceId="TAX_CALC_TAX_CALC_RATE_ID_CSTR_TAX_CLASS_ID_PRD_TAX_CLASS_ID" indexType="btree"> <column name="tax_calculation_rate_id"/> <column name="customer_tax_class_id"/> <column name="product_tax_class_id"/> @@ -122,20 +122,20 @@ <column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Store Id"/> <column xsi:type="varchar" name="value" nullable="false" length="255" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="tax_calculation_rate_title_id"/> </constraint> - <constraint xsi:type="foreign" name="TAX_CALCULATION_RATE_TITLE_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="TAX_CALCULATION_RATE_TITLE_STORE_ID_STORE_STORE_ID" table="tax_calculation_rate_title" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_37FB965F786AD5897BB3AE90470C42AB" table="tax_calculation_rate_title" + <constraint xsi:type="foreign" referenceId="FK_37FB965F786AD5897BB3AE90470C42AB" table="tax_calculation_rate_title" column="tax_calculation_rate_id" referenceTable="tax_calculation_rate" referenceColumn="tax_calculation_rate_id" onDelete="CASCADE"/> - <index name="TAX_CALCULATION_RATE_TITLE_TAX_CALCULATION_RATE_ID_STORE_ID" indexType="btree"> + <index referenceId="TAX_CALCULATION_RATE_TITLE_TAX_CALCULATION_RATE_ID_STORE_ID" indexType="btree"> <column name="tax_calculation_rate_id"/> <column name="store_id"/> </index> - <index name="TAX_CALCULATION_RATE_TITLE_STORE_ID" indexType="btree"> + <index referenceId="TAX_CALCULATION_RATE_TITLE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -151,20 +151,20 @@ default="0" comment="Orders Count"/> <column xsi:type="float" name="tax_base_amount_sum" unsigned="false" nullable="true" comment="Tax Base Amount Sum"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="TAX_ORDER_AGGREGATED_CREATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="TAX_ORDER_AGGREGATED_CREATED_STORE_ID_STORE_STORE_ID" table="tax_order_aggregated_created" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="TAX_ORDER_AGGRED_CREATED_PERIOD_STORE_ID_CODE_PERCENT_ORDER_STS"> + <constraint xsi:type="unique" referenceId="TAX_ORDER_AGGRED_CREATED_PERIOD_STORE_ID_CODE_PERCENT_ORDER_STS"> <column name="period"/> <column name="store_id"/> <column name="code"/> <column name="percent"/> <column name="order_status"/> </constraint> - <index name="TAX_ORDER_AGGREGATED_CREATED_STORE_ID" indexType="btree"> + <index referenceId="TAX_ORDER_AGGREGATED_CREATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -181,20 +181,20 @@ default="0" comment="Orders Count"/> <column xsi:type="float" name="tax_base_amount_sum" unsigned="false" nullable="true" comment="Tax Base Amount Sum"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" name="TAX_ORDER_AGGREGATED_UPDATED_STORE_ID_STORE_STORE_ID" + <constraint xsi:type="foreign" referenceId="TAX_ORDER_AGGREGATED_UPDATED_STORE_ID_STORE_STORE_ID" table="tax_order_aggregated_updated" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="TAX_ORDER_AGGRED_UPDATED_PERIOD_STORE_ID_CODE_PERCENT_ORDER_STS"> + <constraint xsi:type="unique" referenceId="TAX_ORDER_AGGRED_UPDATED_PERIOD_STORE_ID_CODE_PERCENT_ORDER_STS"> <column name="period"/> <column name="store_id"/> <column name="code"/> <column name="percent"/> <column name="order_status"/> </constraint> - <index name="TAX_ORDER_AGGREGATED_UPDATED_STORE_ID" indexType="btree"> + <index referenceId="TAX_ORDER_AGGREGATED_UPDATED_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/Theme/etc/db_schema.xml b/app/code/Magento/Theme/etc/db_schema.xml index ee1185e6e576d..7f3a3fc607947 100644 --- a/app/code/Magento/Theme/etc/db_schema.xml +++ b/app/code/Magento/Theme/etc/db_schema.xml @@ -20,7 +20,7 @@ <column xsi:type="smallint" name="type" padding="6" unsigned="false" nullable="false" identity="false" comment="Theme type: 0:physical, 1:virtual, 2:staging"/> <column xsi:type="text" name="code" nullable="true" comment="Full theme code, including package"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="theme_id"/> </constraint> </table> @@ -35,10 +35,10 @@ <column xsi:type="smallint" name="sort_order" padding="6" unsigned="false" nullable="false" identity="false" default="0" comment="Sort Order"/> <column xsi:type="boolean" name="is_temporary" nullable="false" default="false" comment="Is Temporary File"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="theme_files_id"/> </constraint> - <constraint xsi:type="foreign" name="THEME_FILE_THEME_ID_THEME_THEME_ID" table="theme_file" column="theme_id" + <constraint xsi:type="foreign" referenceId="THEME_FILE_THEME_ID_THEME_THEME_ID" table="theme_file" column="theme_id" referenceTable="theme" referenceColumn="theme_id" onDelete="CASCADE"/> </table> <table name="design_change" resource="default" engine="innodb" comment="Design Changes"> @@ -49,12 +49,12 @@ <column xsi:type="varchar" name="design" nullable="true" length="255" comment="Design"/> <column xsi:type="date" name="date_from" comment="First Date of Design Activity"/> <column xsi:type="date" name="date_to" comment="Last Date of Design Activity"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="design_change_id"/> </constraint> - <constraint xsi:type="foreign" name="DESIGN_CHANGE_STORE_ID_STORE_STORE_ID" table="design_change" + <constraint xsi:type="foreign" referenceId="DESIGN_CHANGE_STORE_ID_STORE_STORE_ID" table="design_change" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index name="DESIGN_CHANGE_STORE_ID" indexType="btree"> + <index referenceId="DESIGN_CHANGE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/Translation/etc/db_schema.xml b/app/code/Magento/Translation/etc/db_schema.xml index 523ef3a1279d0..a0d08467acf06 100644 --- a/app/code/Magento/Translation/etc/db_schema.xml +++ b/app/code/Magento/Translation/etc/db_schema.xml @@ -18,12 +18,12 @@ <column xsi:type="varchar" name="locale" nullable="false" length="20" default="en_US" comment="Locale"/> <column xsi:type="bigint" name="crc_string" padding="20" unsigned="false" nullable="false" identity="false" default="1591228201" comment="Translation String CRC32 Hash"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="key_id"/> </constraint> - <constraint xsi:type="foreign" name="TRANSLATION_STORE_ID_STORE_STORE_ID" table="translation" column="store_id" + <constraint xsi:type="foreign" referenceId="TRANSLATION_STORE_ID_STORE_STORE_ID" table="translation" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="TRANSLATION_STORE_ID_LOCALE_CRC_STRING_STRING"> + <constraint xsi:type="unique" referenceId="TRANSLATION_STORE_ID_LOCALE_CRC_STRING_STRING"> <column name="store_id"/> <column name="locale"/> <column name="crc_string"/> diff --git a/app/code/Magento/Ui/etc/db_schema.xml b/app/code/Magento/Ui/etc/db_schema.xml index d07329df9eb21..e2a04b0cdc72d 100644 --- a/app/code/Magento/Ui/etc/db_schema.xml +++ b/app/code/Magento/Ui/etc/db_schema.xml @@ -20,12 +20,12 @@ <column xsi:type="longtext" name="config" nullable="true" comment="Bookmark config"/> <column xsi:type="datetime" name="created_at" on_update="false" nullable="false" comment="Bookmark created at"/> <column xsi:type="datetime" name="updated_at" on_update="false" nullable="false" comment="Bookmark updated at"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="bookmark_id"/> </constraint> - <constraint xsi:type="foreign" name="UI_BOOKMARK_USER_ID_ADMIN_USER_USER_ID" table="ui_bookmark" + <constraint xsi:type="foreign" referenceId="UI_BOOKMARK_USER_ID_ADMIN_USER_USER_ID" table="ui_bookmark" column="user_id" referenceTable="admin_user" referenceColumn="user_id" onDelete="CASCADE"/> - <index name="UI_BOOKMARK_USER_ID_NAMESPACE_IDENTIFIER" indexType="btree"> + <index referenceId="UI_BOOKMARK_USER_ID_NAMESPACE_IDENTIFIER" indexType="btree"> <column name="user_id"/> <column name="namespace"/> <column name="identifier"/> diff --git a/app/code/Magento/UrlRewrite/etc/db_schema.xml b/app/code/Magento/UrlRewrite/etc/db_schema.xml index af328873deee7..6e0014873202d 100644 --- a/app/code/Magento/UrlRewrite/etc/db_schema.xml +++ b/app/code/Magento/UrlRewrite/etc/db_schema.xml @@ -23,17 +23,17 @@ <column xsi:type="smallint" name="is_autogenerated" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Is rewrite generated automatically flag"/> <column xsi:type="varchar" name="metadata" nullable="true" length="255" comment="Meta data for url rewrite"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="url_rewrite_id"/> </constraint> - <constraint xsi:type="unique" name="URL_REWRITE_REQUEST_PATH_STORE_ID"> + <constraint xsi:type="unique" referenceId="URL_REWRITE_REQUEST_PATH_STORE_ID"> <column name="request_path"/> <column name="store_id"/> </constraint> - <index name="URL_REWRITE_TARGET_PATH" indexType="btree"> + <index referenceId="URL_REWRITE_TARGET_PATH" indexType="btree"> <column name="target_path"/> </index> - <index name="URL_REWRITE_STORE_ID_ENTITY_ID" indexType="btree"> + <index referenceId="URL_REWRITE_STORE_ID_ENTITY_ID" indexType="btree"> <column name="store_id"/> <column name="entity_id"/> </index> diff --git a/app/code/Magento/User/etc/db_schema.xml b/app/code/Magento/User/etc/db_schema.xml index df9b39a27883d..c3356a96b94a7 100644 --- a/app/code/Magento/User/etc/db_schema.xml +++ b/app/code/Magento/User/etc/db_schema.xml @@ -37,10 +37,10 @@ <column xsi:type="timestamp" name="first_failure" on_update="false" nullable="true" comment="First Failure"/> <column xsi:type="timestamp" name="lock_expires" on_update="false" nullable="true" comment="Expiration Lock Dates"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="user_id"/> </constraint> - <constraint xsi:type="unique" name="ADMIN_USER_USERNAME"> + <constraint xsi:type="unique" referenceId="ADMIN_USER_USERNAME"> <column name="username"/> </constraint> </table> @@ -54,12 +54,12 @@ comment="Deprecated"/> <column xsi:type="int" name="last_updated" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Last Updated"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="password_id"/> </constraint> - <constraint xsi:type="foreign" name="ADMIN_PASSWORDS_USER_ID_ADMIN_USER_USER_ID" table="admin_passwords" + <constraint xsi:type="foreign" referenceId="ADMIN_PASSWORDS_USER_ID_ADMIN_USER_USER_ID" table="admin_passwords" column="user_id" referenceTable="admin_user" referenceColumn="user_id" onDelete="CASCADE"/> - <index name="ADMIN_PASSWORDS_USER_ID" indexType="btree"> + <index referenceId="ADMIN_PASSWORDS_USER_ID" indexType="btree"> <column name="user_id"/> </index> </table> diff --git a/app/code/Magento/Variable/etc/db_schema.xml b/app/code/Magento/Variable/etc/db_schema.xml index d89bdb7e710b7..239e3b49983c1 100644 --- a/app/code/Magento/Variable/etc/db_schema.xml +++ b/app/code/Magento/Variable/etc/db_schema.xml @@ -12,10 +12,10 @@ comment="Variable Id"/> <column xsi:type="varchar" name="code" nullable="true" length="255" comment="Variable Code"/> <column xsi:type="varchar" name="name" nullable="true" length="255" comment="Variable Name"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="variable_id"/> </constraint> - <constraint xsi:type="unique" name="VARIABLE_CODE"> + <constraint xsi:type="unique" referenceId="VARIABLE_CODE"> <column name="code"/> </constraint> </table> @@ -28,18 +28,18 @@ default="0" comment="Store Id"/> <column xsi:type="text" name="plain_value" nullable="true" comment="Plain Text Value"/> <column xsi:type="text" name="html_value" nullable="true" comment="Html Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="unique" name="VARIABLE_VALUE_VARIABLE_ID_STORE_ID"> + <constraint xsi:type="unique" referenceId="VARIABLE_VALUE_VARIABLE_ID_STORE_ID"> <column name="variable_id"/> <column name="store_id"/> </constraint> - <constraint xsi:type="foreign" name="VARIABLE_VALUE_STORE_ID_STORE_STORE_ID" table="variable_value" + <constraint xsi:type="foreign" referenceId="VARIABLE_VALUE_STORE_ID_STORE_STORE_ID" table="variable_value" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="VARIABLE_VALUE_VARIABLE_ID_VARIABLE_VARIABLE_ID" table="variable_value" + <constraint xsi:type="foreign" referenceId="VARIABLE_VALUE_VARIABLE_ID_VARIABLE_VARIABLE_ID" table="variable_value" column="variable_id" referenceTable="variable" referenceColumn="variable_id" onDelete="CASCADE"/> - <index name="VARIABLE_VALUE_STORE_ID" indexType="btree"> + <index referenceId="VARIABLE_VALUE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> diff --git a/app/code/Magento/Vault/etc/db_schema.xml b/app/code/Magento/Vault/etc/db_schema.xml index ed1f2adba2142..c647ea92b091a 100644 --- a/app/code/Magento/Vault/etc/db_schema.xml +++ b/app/code/Magento/Vault/etc/db_schema.xml @@ -24,18 +24,18 @@ <column xsi:type="text" name="details" nullable="true" comment="Details"/> <column xsi:type="boolean" name="is_active" nullable="false" default="true"/> <column xsi:type="boolean" name="is_visible" nullable="false" default="true"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="VAULT_PAYMENT_TOKEN_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="VAULT_PAYMENT_TOKEN_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="vault_payment_token" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="VAULT_PAYMENT_TOKEN_PAYMENT_METHOD_CODE_CSTR_ID_GATEWAY_TOKEN"> + <constraint xsi:type="unique" referenceId="VAULT_PAYMENT_TOKEN_PAYMENT_METHOD_CODE_CSTR_ID_GATEWAY_TOKEN"> <column name="payment_method_code"/> <column name="customer_id"/> <column name="gateway_token"/> </constraint> - <constraint xsi:type="unique" name="VAULT_PAYMENT_TOKEN_PUBLIC_HASH"> + <constraint xsi:type="unique" referenceId="VAULT_PAYMENT_TOKEN_PUBLIC_HASH"> <column name="public_hash"/> </constraint> </table> @@ -45,14 +45,14 @@ comment="Order payment Id"/> <column xsi:type="int" name="payment_token_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Payment token Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="order_payment_id"/> <column name="payment_token_id"/> </constraint> - <constraint xsi:type="foreign" name="FK_CF37B9D854256534BE23C818F6291CA2" + <constraint xsi:type="foreign" referenceId="FK_CF37B9D854256534BE23C818F6291CA2" table="vault_payment_token_order_payment_link" column="order_payment_id" referenceTable="sales_order_payment" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="FK_4ED894655446D385894580BECA993862" + <constraint xsi:type="foreign" referenceId="FK_4ED894655446D385894580BECA993862" table="vault_payment_token_order_payment_link" column="payment_token_id" referenceTable="vault_payment_token" referenceColumn="entity_id" onDelete="CASCADE"/> </table> diff --git a/app/code/Magento/Weee/etc/db_schema.xml b/app/code/Magento/Weee/etc/db_schema.xml index 96c3be9740e56..c0a8a3429454f 100644 --- a/app/code/Magento/Weee/etc/db_schema.xml +++ b/app/code/Magento/Weee/etc/db_schema.xml @@ -21,30 +21,30 @@ comment="State"/> <column xsi:type="smallint" name="attribute_id" padding="5" unsigned="true" nullable="false" identity="false" comment="Attribute Id"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="value_id"/> </constraint> - <constraint xsi:type="foreign" name="WEEE_TAX_COUNTRY_DIRECTORY_COUNTRY_COUNTRY_ID" table="weee_tax" + <constraint xsi:type="foreign" referenceId="WEEE_TAX_COUNTRY_DIRECTORY_COUNTRY_COUNTRY_ID" table="weee_tax" column="country" referenceTable="directory_country" referenceColumn="country_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="WEEE_TAX_ENTITY_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="weee_tax" + <constraint xsi:type="foreign" referenceId="WEEE_TAX_ENTITY_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="weee_tax" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="WEEE_TAX_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="weee_tax" + <constraint xsi:type="foreign" referenceId="WEEE_TAX_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID" table="weee_tax" column="website_id" referenceTable="store_website" referenceColumn="website_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="WEEE_TAX_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="weee_tax" + <constraint xsi:type="foreign" referenceId="WEEE_TAX_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID" table="weee_tax" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/> - <index name="WEEE_TAX_WEBSITE_ID" indexType="btree"> + <index referenceId="WEEE_TAX_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="WEEE_TAX_ENTITY_ID" indexType="btree"> + <index referenceId="WEEE_TAX_ENTITY_ID" indexType="btree"> <column name="entity_id"/> </index> - <index name="WEEE_TAX_COUNTRY" indexType="btree"> + <index referenceId="WEEE_TAX_COUNTRY" indexType="btree"> <column name="country"/> </index> - <index name="WEEE_TAX_ATTRIBUTE_ID" indexType="btree"> + <index referenceId="WEEE_TAX_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> </table> diff --git a/app/code/Magento/Widget/etc/db_schema.xml b/app/code/Magento/Widget/etc/db_schema.xml index 149bb27fcdb2a..a82e6aae20296 100644 --- a/app/code/Magento/Widget/etc/db_schema.xml +++ b/app/code/Magento/Widget/etc/db_schema.xml @@ -14,10 +14,10 @@ comment="Widget code for template directive"/> <column xsi:type="varchar" name="widget_type" nullable="true" length="255" comment="Widget Type"/> <column xsi:type="text" name="parameters" nullable="true" comment="Parameters"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="widget_id"/> </constraint> - <index name="WIDGET_WIDGET_CODE" indexType="btree"> + <index referenceId="WIDGET_WIDGET_CODE" indexType="btree"> <column name="widget_code"/> </index> </table> @@ -32,10 +32,10 @@ <column xsi:type="text" name="widget_parameters" nullable="true" comment="Widget parameters"/> <column xsi:type="smallint" name="sort_order" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Sort order"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="instance_id"/> </constraint> - <constraint xsi:type="foreign" name="WIDGET_INSTANCE_THEME_ID_THEME_THEME_ID" table="widget_instance" + <constraint xsi:type="foreign" referenceId="WIDGET_INSTANCE_THEME_ID_THEME_THEME_ID" table="widget_instance" column="theme_id" referenceTable="theme" referenceColumn="theme_id" onDelete="CASCADE"/> </table> <table name="widget_instance_page" resource="default" engine="innodb" comment="Instance of Widget on Page"> @@ -49,13 +49,13 @@ <column xsi:type="varchar" name="page_for" nullable="true" length="25" comment="For instance entities"/> <column xsi:type="text" name="entities" nullable="true" comment="Catalog entities (comma separated)"/> <column xsi:type="varchar" name="page_template" nullable="true" length="255" comment="Path to widget template"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id"/> </constraint> - <constraint xsi:type="foreign" name="WIDGET_INSTANCE_PAGE_INSTANCE_ID_WIDGET_INSTANCE_INSTANCE_ID" + <constraint xsi:type="foreign" referenceId="WIDGET_INSTANCE_PAGE_INSTANCE_ID_WIDGET_INSTANCE_INSTANCE_ID" table="widget_instance_page" column="instance_id" referenceTable="widget_instance" referenceColumn="instance_id" onDelete="CASCADE"/> - <index name="WIDGET_INSTANCE_PAGE_INSTANCE_ID" indexType="btree"> + <index referenceId="WIDGET_INSTANCE_PAGE_INSTANCE_ID" indexType="btree"> <column name="instance_id"/> </index> </table> @@ -64,17 +64,17 @@ comment="Page Id"/> <column xsi:type="int" name="layout_update_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Layout Update Id"/> - <constraint xsi:type="foreign" name="WIDGET_INSTANCE_PAGE_LAYOUT_PAGE_ID_WIDGET_INSTANCE_PAGE_PAGE_ID" + <constraint xsi:type="foreign" referenceId="WIDGET_INSTANCE_PAGE_LAYOUT_PAGE_ID_WIDGET_INSTANCE_PAGE_PAGE_ID" table="widget_instance_page_layout" column="page_id" referenceTable="widget_instance_page" referenceColumn="page_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="WIDGET_INSTANCE_PAGE_LYT_LYT_UPDATE_ID_LYT_UPDATE_LYT_UPDATE_ID" + <constraint xsi:type="foreign" referenceId="WIDGET_INSTANCE_PAGE_LYT_LYT_UPDATE_ID_LYT_UPDATE_LYT_UPDATE_ID" table="widget_instance_page_layout" column="layout_update_id" referenceTable="layout_update" referenceColumn="layout_update_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="WIDGET_INSTANCE_PAGE_LAYOUT_LAYOUT_UPDATE_ID_PAGE_ID"> + <constraint xsi:type="unique" referenceId="WIDGET_INSTANCE_PAGE_LAYOUT_LAYOUT_UPDATE_ID_PAGE_ID"> <column name="layout_update_id"/> <column name="page_id"/> </constraint> - <index name="WIDGET_INSTANCE_PAGE_LAYOUT_PAGE_ID" indexType="btree"> + <index referenceId="WIDGET_INSTANCE_PAGE_LAYOUT_PAGE_ID" indexType="btree"> <column name="page_id"/> </index> </table> @@ -87,10 +87,10 @@ default="0" comment="Sort Order"/> <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="true" default="0" comment="Last Update Timestamp"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="layout_update_id"/> </constraint> - <index name="LAYOUT_UPDATE_HANDLE" indexType="btree"> + <index referenceId="LAYOUT_UPDATE_HANDLE" indexType="btree"> <column name="handle"/> </index> </table> @@ -105,20 +105,20 @@ default="0" comment="Layout Update Id"/> <column xsi:type="boolean" name="is_temporary" nullable="false" default="false" comment="Defines whether Layout Update is Temporary"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="layout_link_id"/> </constraint> - <constraint xsi:type="foreign" name="LAYOUT_LINK_LAYOUT_UPDATE_ID_LAYOUT_UPDATE_LAYOUT_UPDATE_ID" + <constraint xsi:type="foreign" referenceId="LAYOUT_LINK_LAYOUT_UPDATE_ID_LAYOUT_UPDATE_LAYOUT_UPDATE_ID" table="layout_link" column="layout_update_id" referenceTable="layout_update" referenceColumn="layout_update_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="LAYOUT_LINK_STORE_ID_STORE_STORE_ID" table="layout_link" column="store_id" + <constraint xsi:type="foreign" referenceId="LAYOUT_LINK_STORE_ID_STORE_STORE_ID" table="layout_link" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="LAYOUT_LINK_THEME_ID_THEME_THEME_ID" table="layout_link" column="theme_id" + <constraint xsi:type="foreign" referenceId="LAYOUT_LINK_THEME_ID_THEME_THEME_ID" table="layout_link" column="theme_id" referenceTable="theme" referenceColumn="theme_id" onDelete="CASCADE"/> - <index name="LAYOUT_LINK_LAYOUT_UPDATE_ID" indexType="btree"> + <index referenceId="LAYOUT_LINK_LAYOUT_UPDATE_ID" indexType="btree"> <column name="layout_update_id"/> </index> - <index name="LAYOUT_LINK_STORE_ID_THEME_ID_LAYOUT_UPDATE_ID_IS_TEMPORARY" indexType="btree"> + <index referenceId="LAYOUT_LINK_STORE_ID_THEME_ID_LAYOUT_UPDATE_ID_IS_TEMPORARY" indexType="btree"> <column name="store_id"/> <column name="theme_id"/> <column name="layout_update_id"/> diff --git a/app/code/Magento/Wishlist/etc/db_schema.xml b/app/code/Magento/Wishlist/etc/db_schema.xml index 73fcb7ce0cab4..8a02f411ad0db 100644 --- a/app/code/Magento/Wishlist/etc/db_schema.xml +++ b/app/code/Magento/Wishlist/etc/db_schema.xml @@ -16,16 +16,16 @@ default="0" comment="Sharing flag (0 or 1)"/> <column xsi:type="varchar" name="sharing_code" nullable="true" length="32" comment="Sharing encrypted code"/> <column xsi:type="timestamp" name="updated_at" on_update="false" nullable="true" comment="Last updated date"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="wishlist_id"/> </constraint> - <constraint xsi:type="foreign" name="WISHLIST_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="wishlist" + <constraint xsi:type="foreign" referenceId="WISHLIST_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID" table="wishlist" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" name="WISHLIST_CUSTOMER_ID"> + <constraint xsi:type="unique" referenceId="WISHLIST_CUSTOMER_ID"> <column name="customer_id"/> </constraint> - <index name="WISHLIST_SHARED" indexType="btree"> + <index referenceId="WISHLIST_SHARED" indexType="btree"> <column name="shared"/> </index> </table> @@ -42,23 +42,23 @@ <column xsi:type="text" name="description" nullable="true" comment="Short description of wish list item"/> <column xsi:type="decimal" name="qty" scale="4" precision="12" unsigned="false" nullable="false" comment="Qty"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="wishlist_item_id"/> </constraint> - <constraint xsi:type="foreign" name="WISHLIST_ITEM_WISHLIST_ID_WISHLIST_WISHLIST_ID" table="wishlist_item" + <constraint xsi:type="foreign" referenceId="WISHLIST_ITEM_WISHLIST_ID_WISHLIST_WISHLIST_ID" table="wishlist_item" column="wishlist_id" referenceTable="wishlist" referenceColumn="wishlist_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="WISHLIST_ITEM_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + <constraint xsi:type="foreign" referenceId="WISHLIST_ITEM_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" table="wishlist_item" column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="WISHLIST_ITEM_STORE_ID_STORE_STORE_ID" table="wishlist_item" + <constraint xsi:type="foreign" referenceId="WISHLIST_ITEM_STORE_ID_STORE_STORE_ID" table="wishlist_item" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="SET NULL"/> - <index name="WISHLIST_ITEM_WISHLIST_ID" indexType="btree"> + <index referenceId="WISHLIST_ITEM_WISHLIST_ID" indexType="btree"> <column name="wishlist_id"/> </index> - <index name="WISHLIST_ITEM_PRODUCT_ID" indexType="btree"> + <index referenceId="WISHLIST_ITEM_PRODUCT_ID" indexType="btree"> <column name="product_id"/> </index> - <index name="WISHLIST_ITEM_STORE_ID" indexType="btree"> + <index referenceId="WISHLIST_ITEM_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -71,10 +71,10 @@ comment="Product Id"/> <column xsi:type="varchar" name="code" nullable="false" length="255" comment="Code"/> <column xsi:type="text" name="value" nullable="true" comment="Value"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="option_id"/> </constraint> - <constraint xsi:type="foreign" name="FK_A014B30B04B72DD0EAB3EECD779728D6" table="wishlist_item_option" + <constraint xsi:type="foreign" referenceId="FK_A014B30B04B72DD0EAB3EECD779728D6" table="wishlist_item_option" column="wishlist_item_id" referenceTable="wishlist_item" referenceColumn="wishlist_item_id" onDelete="CASCADE"/> </table> diff --git a/app/etc/db_schema.xml b/app/etc/db_schema.xml index be13c28ee029b..d7af9091b238d 100644 --- a/app/etc/db_schema.xml +++ b/app/etc/db_schema.xml @@ -10,7 +10,7 @@ <table name="patch_list" resource="default" comment="List of data/schema patches"> <column xsi:type="int" name="patch_id" identity="true" comment="Patch Auto Increment" /> <column xsi:type="varchar" name="patch_name" length="1024" nullable="false" comment="Patch Class Name" /> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="patch_id" /> </constraint> </table> diff --git a/app/etc/di.xml b/app/etc/di.xml index db979f9b76382..b374645240ff7 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -1484,6 +1484,27 @@ </argument> </arguments> </type> + <virtualType name="Magento\Framework\Setup\Declaration\Schema\Config\SchemaLocator" type="Magento\Framework\Config\SchemaLocator"> + <arguments> + <argument name="realPath" xsi:type="string">urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd</argument> + </arguments> + </virtualType> + <virtualType name="Magento\Framework\Setup\Declaration\Schema\FileSystem\XmlReader" type="Magento\Framework\Config\Reader\Filesystem"> + <arguments> + <argument name="fileResolver" xsi:type="object">Magento\Framework\Config\FileResolverByModule</argument> + <argument name="converter" xsi:type="object">Magento\Framework\Setup\Declaration\Schema\Config\Converter</argument> + <argument name="schemaLocator" xsi:type="object">Magento\Framework\Setup\Declaration\Schema\Config\SchemaLocator</argument> + <argument name="fileName" xsi:type="string">db_schema.xml</argument> + <argument name="idAttributes" xsi:type="array"> + <item name="/schema/table" xsi:type="string">name</item> + <item name="/schema/table/column" xsi:type="string">name</item> + <item name="/schema/table/constraint" xsi:type="string">referenceId</item> + <item name="/schema/table/index" xsi:type="string">referenceId</item> + <item name="/schema/table/index/column" xsi:type="string">name</item> + <item name="/schema/table/constraint/column" xsi:type="string">name</item> + </argument> + </arguments> + </virtualType> <type name="Magento\Framework\Setup\Declaration\Schema\OperationsExecutor"> <arguments> <argument name="operations" xsi:type="array"> diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php index ed3f6326cd604..3882afb9f4360 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php @@ -5,6 +5,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\Setup\Declaration\Schema\Config; /** @@ -23,7 +25,7 @@ class Converter implements \Magento\Framework\Config\ConverterInterface * @param \DOMDocument $source * @return array */ - public function convert($source) + public function convert($source): array { $output = $this->recursiveConvert($this->getTablesNode($source)); return $output; @@ -37,7 +39,7 @@ public function convert($source) * @param \DOMDocument $element * @return \DOMNodeList */ - private function getTablesNode(\DOMDocument $element) + private function getTablesNode(\DOMDocument $element): \DOMNodeList { return $element->getElementsByTagName('table'); } @@ -48,21 +50,21 @@ private function getTablesNode(\DOMDocument $element) * @param \Traversable $source * @return array */ - private function recursiveConvert(\Traversable $source) + private function recursiveConvert(\Traversable $source): array { $output = []; foreach ($source as $element) { if ($element instanceof \DOMElement) { - $key = $element->getAttribute('name'); + $key = $this->getIdAttributeValue($element); if ($element->hasChildNodes()) { $output[$element->tagName][$key] = array_replace( $this->recursiveConvert($element->childNodes), - $this->interpretateAttributes($element) + $this->interpretAttributes($element) ); - } else if ($this->hasAttributesExceptName($element)) { - $output[$element->tagName][$key] = $this->interpretateAttributes($element); + } elseif ($this->hasAttributesExceptIdAttribute($element)) { + $output[$element->tagName][$key] = $this->interpretAttributes($element); } else { $output[$element->tagName][$key] = $key; } @@ -73,25 +75,48 @@ private function recursiveConvert(\Traversable $source) } /** - * Check whether we have any attributes except name XSI:TYPE is in another namespace. - * Note: name is mandatory attribute. + * Provides the value of the ID attribute for each element. + * + * @param \DOMElement $element + * @return string + */ + private function getIdAttributeValue(\DOMElement $element): string + { + $idAttributeValue = ''; + switch ($element->tagName) { + case ('table'): + case ('column'): + $idAttributeValue = $element->getAttribute('name'); + break; + case ('index'): + case ('constraint'): + $idAttributeValue = $element->getAttribute('referenceId'); + break; + } + + return $idAttributeValue; + } + + /** + * Check whether we have any attributes except ID attribute. * * @param \DOMElement $element * @return bool */ - private function hasAttributesExceptName(\DOMElement $element) + private function hasAttributesExceptIdAttribute(\DOMElement $element) { return $element->hasAttribute('xsi:type') || $element->attributes->length >= 2; } /** * Mix attributes that comes from XML schema with default ones. + * * So if you will not have some attribute in schema - it will be taken from default one. * * @param \DOMElement $domElement - * @return mixed + * @return array */ - private function interpretateAttributes(\DOMElement $domElement) + private function interpretAttributes(\DOMElement $domElement): array { $attributes = $this->getAttributes($domElement); $xsiType = $domElement->getAttribute('xsi:type'); @@ -109,7 +134,7 @@ private function interpretateAttributes(\DOMElement $domElement) * @param \DOMElement $element * @return array */ - private function getAttributes(\DOMElement $element) + private function getAttributes(\DOMElement $element): array { $attributes = []; $attributeNodes = $element->attributes; diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/SchemaLocator.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/SchemaLocator.php deleted file mode 100644 index 5319c469f0458..0000000000000 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/SchemaLocator.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\Setup\Declaration\Schema\Config; - -/** - * This is system class that provides .xsd file for validation XML schema. - */ -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; - - /** - * Constructor. - * - * @param \Magento\Framework\Config\Dom\UrnResolver $urnResolver - * @param string $schemaUrn - */ - public function __construct( - \Magento\Framework\Config\Dom\UrnResolver $urnResolver, - $schemaUrn = 'urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd' - ) { - $this->_schema = $urnResolver->getRealPath($schemaUrn); - $this->_perFileSchema = $this->_schema; - } - - /** - * Get path to merged config schema. - * - * @return string|null - */ - public function getSchema() - { - return $this->_schema; - } - - /** - * Get path to pre file validation schema. - * - * @return string|null - */ - public function getPerFileSchema() - { - return $this->_perFileSchema; - } -} diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php index 830fcb293a8f1..735b8273019f7 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\Setup\Declaration\Schema\Declaration; use Magento\Framework\DB\Adapter\AdapterInterface; @@ -19,8 +21,7 @@ use Magento\Framework\Setup\Declaration\Schema\Sharding; /** - * This type of builder is responsible for converting ENTIRE data, that comes from XML - * into DTO`s format, with aggregation root: Schema. + * This type of builder is responsible for converting ENTIRE data, that comes from XML into DTO`s format. * * Note: SchemaBuilder can not be used for one structural element, like column or constraint * because it should have references to other DTO objects. @@ -102,6 +103,7 @@ public function __construct( /** * Add tables data to builder. + * * Tables data holds tables information: columns, constraints, indexes, attributes. * * @param array $tablesData @@ -140,7 +142,7 @@ private function validate(Schema $schema) * @throws Exception * @return Schema */ - public function build(Schema $schema) + public function build(Schema $schema): Schema { foreach ($this->tablesData as $tableData) { if (!$schema->getTableByName($tableData['name'])) { @@ -161,7 +163,7 @@ public function build(Schema $schema) * @param array $tableData * @return string */ - private function getStructuralElementResource(array $tableData) + private function getStructuralElementResource(array $tableData): string { return isset($tableData['resource']) && $this->sharding->canUseResource($tableData['resource']) ? $tableData['resource'] : 'default'; @@ -173,7 +175,7 @@ private function getStructuralElementResource(array $tableData) * @param array $structuralElementData * @return bool */ - private function isDisabled($structuralElementData) + private function isDisabled(array $structuralElementData): bool { return isset($structuralElementData['disabled']) && $this->booleanUtils->toBoolean($structuralElementData['disabled']); @@ -181,14 +183,15 @@ private function isDisabled($structuralElementData) /** * Instantiate column DTO objects from array. + * * If column was renamed new key will be associated to it. * - * @param array $tableData - * @param string $resource - * @param Table $table + * @param array $tableData + * @param string $resource + * @param Table $table * @return array */ - private function processColumns(array $tableData, $resource, Table $table) + private function processColumns(array $tableData, string $resource, Table $table): array { $columns = []; @@ -208,12 +211,12 @@ private function processColumns(array $tableData, $resource, Table $table) /** * Process generic data that is support by all 3 child types: columns, constraints, indexes. * - * @param array $elementData - * @param Table $table - * @param $resource + * @param array $elementData + * @param string $resource + * @param Table $table * @return array */ - private function processGenericData(array $elementData, $resource, Table $table) + private function processGenericData(array $elementData, string $resource, Table $table): array { $elementData['table'] = $table; $elementData['resource'] = $resource; @@ -223,13 +226,14 @@ private function processGenericData(array $elementData, $resource, Table $table) /** * Process tables and add them to schema. + * * If table already exists - then we need to skip it. * * @param Schema $schema - * @param array $tableData - * @return \Magento\Framework\Setup\Declaration\Schema\Dto\Table + * @param array $tableData + * @return Table */ - private function processTable(Schema $schema, array $tableData) + private function processTable(Schema $schema, array $tableData): Table { if (!$schema->getTableByName($tableData['name'])) { $resource = $this->getStructuralElementResource($tableData); @@ -250,11 +254,13 @@ private function processTable(Schema $schema, array $tableData) } /** + * Provides column by name. + * * @param string $columnName * @param Table $table * @return Column */ - private function getColumnByName(string $columnName, Table $table) + private function getColumnByName(string $columnName, Table $table): Column { $columnCandidate = $table->getColumnByName($columnName); @@ -274,7 +280,7 @@ private function getColumnByName(string $columnName, Table $table) * @param Table $table * @return array */ - private function convertColumnNamesToObjects(array $columnNames, Table $table) + private function convertColumnNamesToObjects(array $columnNames, Table $table): array { $columns = []; @@ -288,20 +294,18 @@ private function convertColumnNamesToObjects(array $columnNames, Table $table) /** * Provides the full index name based on the prefix value. * - * @param string $name * @param Table $table * @param array $columns * @param string $type * @return string */ private function getFullIndexName( - string $name, Table $table, array $columns, string $type = AdapterInterface::INDEX_TYPE_INDEX - ) { + ): string { if (AdapterInterface::INDEX_TYPE_PRIMARY === $type) { - return $name; + return strtoupper(AdapterInterface::INDEX_TYPE_PRIMARY); } $tableName = $this->tableNameResolver->getNameOfOriginTable($table->getName()); @@ -317,12 +321,12 @@ private function getFullIndexName( /** * Convert and instantiate index objects. * - * @param array $tableData - * @param $resource - * @param Table $table + * @param array $tableData + * @param string $resource + * @param Table $table * @return Index[] */ - private function processIndexes(array $tableData, $resource, Table $table) + private function processIndexes(array $tableData, string $resource, Table $table): array { if (!isset($tableData['index'])) { return []; @@ -345,7 +349,6 @@ private function processIndexes(array $tableData, $resource, Table $table) } $indexData['name'] = $this->getFullIndexName( - $indexData['name'], $table, $indexData['column'], $indexType @@ -363,12 +366,12 @@ private function processIndexes(array $tableData, $resource, Table $table) * Convert and instantiate constraint objects. * * @param array $tableData - * @param $resource + * @param string $resource * @param Schema $schema * @param Table $table * @return Constraint[] */ - private function processConstraints(array $tableData, $resource, Schema $schema, Table $table) + private function processConstraints(array $tableData, string $resource, Schema $schema, Table $table): array { if (!isset($tableData['constraint'])) { return []; @@ -422,7 +425,6 @@ private function processConstraints(array $tableData, $resource, Schema $schema, $constraints[$constraint->getName()] = $constraint; } else { $constraintData['name'] = $this->getFullIndexName( - $constraintData['name'], $table, $constraintData['column'], $constraintData['type'] diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/FileSystem/XmlReader.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/FileSystem/XmlReader.php deleted file mode 100644 index bd835c35fd890..0000000000000 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/FileSystem/XmlReader.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Framework\Setup\Declaration\Schema\FileSystem; - -use Magento\Framework\Config\FileResolverByModule; -use Magento\Framework\Config\ReaderInterface; - -/** - * DB Schema XML configuration reader. - * Reads schema config from db_schema.xml files in enabled modules. - */ -class XmlReader extends \Magento\Framework\Config\Reader\Filesystem implements ReaderInterface -{ - /** - * Attributes by names of which we will do nodes merge. - * - * @var array - */ - private $idAttributes = [ - '/schema/table' => 'name', - '/schema/table/column' => 'name', - '/schema/table/constraint' => 'name', - '/schema/table/index' => 'name', - '/schema/table/index/column' => 'name', - '/schema/table/constraint/column' => 'name', - ]; - - /** - * XmlReader constructor. - * - * @param FileResolverByModule $fileResolver - * @param \Magento\Framework\Setup\Declaration\Schema\Config\Converter $converter - * @param \Magento\Framework\Setup\Declaration\Schema\Config\SchemaLocator $schemaLocator - * @param \Magento\Framework\Config\ValidationStateInterface $validationState - * @param string $fileName - * @param string $domDocumentClass - * @param string $defaultScope - */ - public function __construct( - FileResolverByModule $fileResolver, - \Magento\Framework\Setup\Declaration\Schema\Config\Converter $converter, - \Magento\Framework\Setup\Declaration\Schema\Config\SchemaLocator $schemaLocator, - \Magento\Framework\Config\ValidationStateInterface $validationState, - $fileName = 'db_schema.xml', - $domDocumentClass = \Magento\Framework\Config\Dom::class, - $defaultScope = 'global' - ) { - parent::__construct( - $fileResolver, - $converter, - $schemaLocator, - $validationState, - $fileName, - $this->idAttributes, - $domDocumentClass, - $defaultScope - ); - } -} diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd index 8c264bd95a076..3eed77c37caac 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd @@ -10,6 +10,6 @@ <xs:attributeGroup name="baseConstraint"> <xs:attributeGroup ref="basicOperations" /> - <xs:attribute name="name" type="nameType" use="required" /> + <xs:attribute name="referenceId" type="referenceIdType" use="required" /> </xs:attributeGroup> </xs:schema> diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd index ead4fc5604fcb..d6436204a32e5 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd @@ -19,7 +19,7 @@ </xs:sequence> <xs:attribute name="indexType" type="indexType" /> - <xs:attribute name="name" type="nameType" /> + <xs:attribute name="referenceId" type="referenceIdType" /> <xs:attribute name="disabled" type="xs:boolean" /> </xs:complexType> diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/name.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/name.xsd index 82db095d66821..dbebdefbda0c2 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/name.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/name.xsd @@ -16,4 +16,18 @@ <xs:maxLength value="64" /> </xs:restriction> </xs:simpleType> + <xs:simpleType name="referenceIdType"> + <xs:union memberTypes="nameType"> + <xs:simpleType> + <xs:annotation> + <xs:documentation> + The attribute can contain only [A-Z0-9_]. + </xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:pattern value="[A-Z0-9_]+" /> + </xs:restriction> + </xs:simpleType> + </xs:union> + </xs:simpleType> </xs:schema> diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd index 66cd19d051280..54c8f19753070 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd @@ -55,7 +55,7 @@ <xs:element name="constraint" /> <xs:element name="index" type="index" /> </xs:choice> - <xs:attribute name="name" type="xs:string" /> + <xs:attribute name="name" type="xs:string" use="required" /> <xs:attribute name="resource" type="resourceType" /> <xs:attribute name="engine" type="engineType" /> <xs:attribute name="comment" type="xs:string" /> From 3d3b45f384b2166fc86b5d4ec8eb856236336f64 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 19 Oct 2018 18:54:47 +0300 Subject: [PATCH 383/812] GraphQL-174: Absolute image paths for Products --- .../Model/Resolver/Product/ProductImage.php | 31 +------ .../Resolver/Product/ProductImage/Label.php | 85 +++++++++++++++++++ .../Resolver/Product/ProductImage/Path.php | 45 ++++++++++ .../Resolver/Product/ProductImage/Url.php | 75 ++++++++++++++++ .../CatalogGraphQl/etc/schema.graphqls | 6 +- 5 files changed, 211 insertions(+), 31 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php index 3caa79e68c235..d1566162472b0 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage.php @@ -8,7 +8,6 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\ImageFactory; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -19,22 +18,6 @@ */ class ProductImage implements ResolverInterface { - /** - * Product image factory - * - * @var ImageFactory - */ - private $productImageFactory; - - /** - * @param ImageFactory $productImageFactory - */ - public function __construct( - ImageFactory $productImageFactory - ) { - $this->productImageFactory = $productImageFactory; - } - /** * @inheritdoc */ @@ -48,22 +31,14 @@ public function resolve( if (!isset($value['model'])) { throw new LocalizedException(__('"model" value should be specified')); } + /** @var Product $product */ $product = $value['model']; $imageType = $field->getName(); - $imagePath = $product->getData($imageType); - $imageLabel = $product->getData($imageType . '_' . 'label') ?? $product->getName(); - - $image = $this->productImageFactory->create(); - $image->setDestinationSubdir($imageType) - ->setBaseFile($imagePath); - $imageUrl = $image->getUrl(); - return [ - 'url' => $imageUrl, - 'path' => $imagePath, - 'label' => $imageLabel, + 'model' => $product, + 'image_type' => $imageType, ]; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php new file mode 100644 index 0000000000000..5b752e7184893 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php @@ -0,0 +1,85 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductImage; + +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\ResourceModel\Product as ProductResourceModel; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Store\Model\StoreManagerInterface; + +/** + * Returns product's image label + */ +class Label implements ResolverInterface +{ + /** + * @var ProductResourceModel + */ + private $productResource; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @param ProductResourceModel $productResource + * @param StoreManagerInterface $storeManager + */ + public function __construct( + ProductResourceModel $productResource, + StoreManagerInterface $storeManager + ) { + $this->productResource = $productResource; + $this->storeManager = $storeManager; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['image_type'])) { + throw new LocalizedException(__('"image_type" value should be specified')); + } + + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + + /** @var Product $product */ + $product = $value['model']; + + $imageLabel = $this->getImageLabel((int)$product->getEntityId(), $value['image_type']); + return $imageLabel; + } + + /** + * @param int $productId + * @param string $imageType + * @return string + */ + private function getImageLabel(int $productId, string $imageType): string + { + $storeId = $this->storeManager->getStore()->getId(); + + $imageLabel = $this->productResource->getAttributeRawValue($productId, $imageType . '_label', $storeId); + if (empty($imageLabel)) { + $imageLabel = $this->productResource->getAttributeRawValue($productId, 'name', $storeId); + } + return $imageLabel; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php new file mode 100644 index 0000000000000..249f1dc40b19a --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductImage; + +use Magento\Catalog\Model\Product; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; + +/** + * Returns product's image path + */ +class Path implements ResolverInterface +{ + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['image_type'])) { + throw new LocalizedException(__('"image_type" value should be specified')); + } + + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + + /** @var Product $product */ + $product = $value['model']; + + $imagePath = $product->getData($value['image_type']); + return $imagePath; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php new file mode 100644 index 0000000000000..d9136e742b178 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php @@ -0,0 +1,75 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductImage; + +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\ImageFactory; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; + +/** + * Returns product's image url + */ +class Url implements ResolverInterface +{ + /** + * @var ImageFactory + */ + private $productImageFactory; + + /** + * @param ImageFactory $productImageFactory + */ + public function __construct( + ImageFactory $productImageFactory + ) { + $this->productImageFactory = $productImageFactory; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['image_type'])) { + throw new LocalizedException(__('"image_type" value should be specified')); + } + + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + + /** @var Product $product */ + $product = $value['model']; + $imagePath = $product->getData($value['image_type']); + + $imageUrl = $this->getImageUrl($value['image_type'], $imagePath); + return $imageUrl; + } + + /** + * @param string $imageType + * @param string $imagePath + * @return string + */ + private function getImageUrl(string $imageType, string $imagePath): string + { + $image = $this->productImageFactory->create(); + $image->setDestinationSubdir($imageType) + ->setBaseFile($imagePath); + $imageUrl = $image->getUrl(); + return $imageUrl; + } +} diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index f87e524a26b3f..fb042c7e59c15 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -350,9 +350,9 @@ type CustomizableFileValue @doc(description: "CustomizableFileValue defines the } type ProductImage @doc(description: "Product image information. Contains image relative path, URL and label") { - url: String - path: String - label: String + url: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Url") + path: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Path") + label: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Label") } interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CustomizableOptionTypeResolver") @doc(description: "The CustomizableOptionInterface contains basic information about a customizable option. It can be implemented by several types of configurable options.") { From a02ba47637dfce624ee0afceeed6c2851fa85c13 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Thu, 18 Oct 2018 14:36:14 -0500 Subject: [PATCH 384/812] MAGETWO-95002: [GraphQL] Product search do not work with elasticsearch --- .../Model/Resolver/Products/Query/Search.php | 17 +++++- app/code/Magento/Elasticsearch/etc/di.xml | 8 +++ .../Magento/GraphQl/Controller/GraphQl.php | 1 + .../Search/Model/Search/PageSizeProvider.php | 53 ++++++++++++++++ .../Model/Search/PageSizeProviderTest.php | 61 +++++++++++++++++++ 5 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Search/Model/Search/PageSizeProvider.php create mode 100644 app/code/Magento/Search/Test/Unit/Model/Search/PageSizeProviderTest.php 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 c4da59fd2cedf..80d65e96625e8 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php @@ -12,7 +12,6 @@ use Magento\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\Helper\Filter as FilterHelper; use Magento\CatalogGraphQl\Model\Resolver\Products\SearchResult; use Magento\CatalogGraphQl\Model\Resolver\Products\SearchResultFactory; -use Magento\Framework\EntityManager\EntityManager; use Magento\Search\Api\SearchInterface; /** @@ -45,31 +44,42 @@ class Search */ private $metadataPool; + /** + * @var \Magento\CatalogSearch\Model\Search\PageSizeProvider + */ + private $pageSizeProvider; + /** * @param SearchInterface $search * @param FilterHelper $filterHelper * @param Filter $filterQuery * @param SearchResultFactory $searchResultFactory + * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool + * @param \Magento\Search\Model\Search\PageSizeProvider $pageSize */ public function __construct( SearchInterface $search, FilterHelper $filterHelper, Filter $filterQuery, SearchResultFactory $searchResultFactory, - \Magento\Framework\EntityManager\MetadataPool $metadataPool + \Magento\Framework\EntityManager\MetadataPool $metadataPool, + \Magento\Search\Model\Search\PageSizeProvider $pageSize ) { $this->search = $search; $this->filterHelper = $filterHelper; $this->filterQuery = $filterQuery; $this->searchResultFactory = $searchResultFactory; $this->metadataPool = $metadataPool; + $this->pageSizeProvider = $pageSize; } /** * Return results of full text catalog search of given term, and will return filtered results if filter is specified * * @param SearchCriteriaInterface $searchCriteria + * @param ResolveInfo $info * @return SearchResult + * @throws \Exception */ public function getResult(SearchCriteriaInterface $searchCriteria, ResolveInfo $info) : SearchResult { @@ -79,7 +89,8 @@ public function getResult(SearchCriteriaInterface $searchCriteria, ResolveInfo $ $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 - $searchCriteria->setPageSize(PHP_INT_MAX); + $pageSize = $this->pageSizeProvider->getMaxPageSize(); + $searchCriteria->setPageSize($pageSize); $searchCriteria->setCurrentPage(0); $itemsResults = $this->search->search($searchCriteria); diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index 0cfaba845fd6a..3ce2639674d8b 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -271,4 +271,12 @@ </argument> </arguments> </type> + <type name="Magento\Search\Model\Search\PageSizeProvider"> + <arguments> + <argument name="pageSizeBySearchEngine" xsi:type="array"> + <item name="elasticsearch" xsi:type="number">2147483647</item> + <item name="elasticsearch5" xsi:type="number">2147483647</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index c4a0b55de9bfc..fecbf9c430f54 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -108,6 +108,7 @@ public function dispatch(RequestInterface $request) : ResponseInterface try { /** @var Http $request */ $this->requestProcessor->processHeaders($request); + //\Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class)->critical($request->getContent()); $data = $this->jsonSerializer->unserialize($request->getContent()); $query = isset($data['query']) ? $data['query'] : ''; diff --git a/app/code/Magento/Search/Model/Search/PageSizeProvider.php b/app/code/Magento/Search/Model/Search/PageSizeProvider.php new file mode 100644 index 0000000000000..43e20aae8e697 --- /dev/null +++ b/app/code/Magento/Search/Model/Search/PageSizeProvider.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Search\Model\Search; + +/** + * Returns max page size by search engine name + */ +class PageSizeProvider +{ + /** + * @var \Magento\Search\Model\EngineResolver + */ + private $engineResolver; + + /** + * @var array + */ + private $pageSizeBySearchEngine; + + /** + * @param \Magento\Search\Model\EngineResolver $engineResolver + * @param array $pageSizeBySearchEngine + */ + public function __construct( + \Magento\Search\Model\EngineResolver $engineResolver, + array $pageSizeBySearchEngine = [] + ) { + $this->engineResolver = $engineResolver; + $this->pageSizeBySearchEngine = $pageSizeBySearchEngine; + } + + /** + * Returns max_page_size depends on engine + * + * @return integer + */ + public function getMaxPageSize() : int + { + $searchEngine = $this->engineResolver->getCurrentSearchEngine(); + + $pageSize = PHP_INT_MAX; + if (isset($this->pageSizeBySearchEngine[$searchEngine])) { + $pageSize = $this->pageSizeBySearchEngine[$searchEngine]; + } + + return (int)$pageSize; + } +} diff --git a/app/code/Magento/Search/Test/Unit/Model/Search/PageSizeProviderTest.php b/app/code/Magento/Search/Test/Unit/Model/Search/PageSizeProviderTest.php new file mode 100644 index 0000000000000..982d00bd9f648 --- /dev/null +++ b/app/code/Magento/Search/Test/Unit/Model/Search/PageSizeProviderTest.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Search\Test\Unit\Model\Search; + +use Magento\Search\Model\Search\PageSizeProvider; + +class PageSizeProviderTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var PageSizeProvider + */ + private $model; + + /** + * @var \Magento\Search\Model\EngineResolver|\PHPUnit_Framework_MockObject_MockObject + */ + private $pageSizeBySearchEngineMock; + + public function setUp() + { + $this->pageSizeBySearchEngineMock = $this->getMockBuilder(\Magento\Search\Model\EngineResolver::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->model = new PageSizeProvider( + + $this->pageSizeBySearchEngineMock, + ['search' => 10, + 'catalogSearch3' => 11 + ] + ); + } + + /** + * @param string $searchEngine + * @param int $size + * @dataProvider getPageSizeDataProvider + */ + public function testGetPageSize($searchEngine, $size) + { + $this->pageSizeBySearchEngineMock + ->expects($this->once()) + ->method('getCurrentSearchEngine') + ->willReturn($searchEngine); + $this->assertEquals($size, $this->model->getMaxPageSize()); + } + + public function getPageSizeDataProvider() + { + return [ + ['search', 10], + ['catalogSearch3', 11], + ['newSearch', PHP_INT_MAX] + ]; + } +} From 6f6fd69f1cf86976ed3dab7208d578c513deddfd Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Fri, 19 Oct 2018 11:25:09 -0500 Subject: [PATCH 385/812] MAGETWO-95002: [GraphQL] Product search do not work with elasticsearch --- app/code/Magento/GraphQl/Controller/GraphQl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index fecbf9c430f54..d957f394ee714 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -108,7 +108,7 @@ public function dispatch(RequestInterface $request) : ResponseInterface try { /** @var Http $request */ $this->requestProcessor->processHeaders($request); - //\Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class)->critical($request->getContent()); + $data = $this->jsonSerializer->unserialize($request->getContent()); $query = isset($data['query']) ? $data['query'] : ''; From 43f94172453d1b714884825431f6df9c9aba63d4 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 19 Oct 2018 11:38:28 -0500 Subject: [PATCH 386/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../etc/db_schema.xml | 10 +++++----- .../revisions/base_update/db_schema.xml | 8 ++++---- .../revisions/before_rollback/db_schema.xml | 2 +- .../column_modifications/db_schema.xml | 10 +++++----- .../revisions/column_removals/db_schema.xml | 10 +++++----- .../constraint_modifications/db_schema.xml | 18 +++++++++--------- .../revisions/drop_table/db_schema.xml | 2 +- .../foreign_key_interpreter/db_schema.xml | 2 +- .../revisions/old_diff/db_schema.xml | 8 ++++---- .../etc/db_schema.xml | 6 +++--- .../etc/db_schema.xml | 2 +- .../remove_title_column/db_schema.xml | 2 +- .../restore_title_column/db_schema.xml | 2 +- .../etc/db_schema.xml | 6 +++--- .../etc/db_schema.xml | 10 +++++----- .../db_schema.xml | 4 ++-- .../invalid_primary_key/db_schema.xml | 2 +- 17 files changed, 52 insertions(+), 52 deletions(-) diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml index 5b8a4c8f37c99..1c4e7b6b6da97 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml @@ -21,7 +21,7 @@ <column xsi:type="bigint" name="bigint_default_nullable" padding="2" nullable="true" default="1" unsigned="true"/> <column xsi:type="bigint" name="bigint_not_default_not_nullable" padding="2" nullable="false" unsigned="true"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> </constraint> </table> @@ -30,7 +30,7 @@ nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> + <constraint xsi:type="unique" referenceId="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -53,15 +53,15 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml index 7384c4ed7baab..af66686e77b42 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml @@ -9,7 +9,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="reference_table" resource="default" comment="Reference table"> <column xsi:type="smallint" name="smallint_ref" padding="6" nullable="false" unsigned="false" identity="true" comment="Smallint"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="smallint_ref"/> </constraint> </table> @@ -22,14 +22,14 @@ <column xsi:type="mediumtext" name="mediumtext" comment="Mediumtext"/> <column xsi:type="varchar" name="varchar" length="254" nullable="true" comment="Varchar"/> <column xsi:type="boolean" name="boolean" comment="Boolean"/> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="smallint" table="test_table" referenceTable="reference_table" referenceColumn="smallint_ref" onDelete="CASCADE"/> - <index name="TEST_TABLE_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_BIGINT" indexType="btree"> <column name="bigint"/> </index> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml index 4d3d51b9c0237..8c42f9efd129a 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml @@ -20,7 +20,7 @@ <table name="store_owner" comment="Store owner information" engine="innodb" resource="default"> <column name="owner_id" xsi:type="smallint" nullable="false" unsigned="false" identity="true" /> <column name="store_owner_name" onCreate="migrateDataFrom(label)" xsi:type="varchar" length="255" comment="Store Owner Name" /> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="owner_id" /> </constraint> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml index 0adcd5c52f962..4f9a5ab6d5a92 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml @@ -21,7 +21,7 @@ <column xsi:type="bigint" name="bigint_default_nullable" padding="2" nullable="true" default="123" unsigned="true"/> <column xsi:type="bigint" name="bigint_not_default_not_nullable" nullable="false" unsigned="false"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> </constraint> </table> @@ -29,7 +29,7 @@ <column xsi:type="int" name="int_auto_increment_with_nullable" padding="15" unsigned="true" nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> + <constraint xsi:type="unique" referenceId="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -52,15 +52,15 @@ <column xsi:type="boolean" name="boolean" default="true"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml index 4b78f436eab37..a3c4fe010fd35 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml @@ -20,14 +20,14 @@ <column xsi:type="bigint" name="bigint_default_nullable" padding="2" nullable="true" default="1" unsigned="true"/> <column xsi:type="bigint" name="bigint_not_default_not_nullable" padding="2" nullable="false" unsigned="true"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> </constraint> </table> <table name="auto_increment_test" resource="default"> <column xsi:type="int" name="int_auto_increment_with_nullable" identity="true" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> + <constraint xsi:type="unique" referenceId="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -50,15 +50,15 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="false"/> <!--Constraints--> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml index 68f2810e8eed7..93e6e13eb36f8 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml @@ -22,11 +22,11 @@ <column xsi:type="bigint" name="bigint_default_nullable" padding="2" nullable="true" default="1" unsigned="true"/> <column xsi:type="bigint" name="bigint_not_default_not_nullable" padding="2" nullable="false" unsigned="true"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> <column name="smallint_ref"/> </constraint> - <constraint xsi:type="unique" name="REFERENCE_TABLE_SMALLINT_REF"> + <constraint xsi:type="unique" referenceId="REFERENCE_TABLE_SMALLINT_REF"> <column name="smallint_ref"/> </constraint> </table> @@ -35,7 +35,7 @@ nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> + <constraint xsi:type="unique" referenceId="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -60,23 +60,23 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_FLOAT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_FLOAT"> <column name="smallint"/> <column name="float"/> </constraint> - <constraint xsi:type="unique" name="TEST_TABLE_DOUBLE"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_DOUBLE"> <column name="double"/> </constraint> - <constraint xsi:type="foreign" name="some_foreign_key_new" column="smallint_main" table="test_table" + <constraint xsi:type="foreign" referenceId="some_foreign_key_new" column="smallint_main" table="test_table" referenceTable="reference_table" referenceColumn="smallint_ref" onDelete="CASCADE"/> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="SET NULL"/> - <constraint xsi:type="foreign" name="FK_FB77604C299EB8612D01E4AF8D9931F2" + <constraint xsi:type="foreign" referenceId="FK_FB77604C299EB8612D01E4AF8D9931F2" column="integer_main" table="test_table" referenceTable="auto_increment_test" referenceColumn="int_auto_increment_with_nullable"/> <!--Indexes--> - <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml index 0a0131e500641..8a73d9e225546 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml @@ -12,7 +12,7 @@ nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> + <constraint xsi:type="unique" referenceId="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml index e4a5ca05d02fe..479c4c87f6143 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml @@ -12,7 +12,7 @@ </table> <table name="test_table" resource="default"> <column xsi:type="tinyint" name="tinyint" default="0" padding="7" nullable="true" unsigned="false"/> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref"/> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml index 6b92440ca92f5..1347a1ba8e3b1 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml @@ -9,7 +9,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="reference_table" resource="default" comment="Reference table"> <column xsi:type="smallint" name="smallint_ref" padding="6" nullable="false" unsigned="false" identity="true" comment="Smallint"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="smallint_ref"/> </constraint> </table> @@ -22,14 +22,14 @@ <column xsi:type="mediumtext" name="mediumtext" comment="Mediumtext"/> <column xsi:type="varchar" name="varchar" length="254" nullable="true" comment="Varchar"/> <column xsi:type="boolean" name="boolean" comment="Boolean"/> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="smallint" table="test_table" referenceTable="reference_table" referenceColumn="smallint_ref" onDelete="CASCADE"/> - <index name="TEST_TABLE_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_BIGINT" indexType="btree"> <column name="bigint"/> </index> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml index b6ff634e6ef1d..9bd6c438455b2 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="tinyint" name="tinyint_ref" padding="7" nullable="false" identity="true" unsigned="false"/> <column xsi:type="int" name="some_integer" default="0" nullable="false" unsigned="false"/> <column xsi:type="varchar" name="for_patch_testing" comment="For patch testing" /> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> </constraint> </table> @@ -21,10 +21,10 @@ <column xsi:type="tinyint" name="tinyint" padding="7" nullable="true" unsigned="false"/> <column xsi:type="varchar" name="varchar" length="254" nullable="true"/> <column xsi:type="varbinary" name="varbinary" default="10101" /> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="CASCADE"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="smallint" /> </constraint> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/etc/db_schema.xml index 4520cd9e4d406..8082157524ad4 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/etc/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="int" name="page_id" nullable="false" /> <column xsi:type="varchar" name="email" nullable="false" /> <column xsi:type="varchar" name="title" /> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id" /> <column name="email" /> </constraint> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/remove_title_column/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/remove_title_column/db_schema.xml index 9d868c0168826..0eeff4174870a 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/remove_title_column/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/remove_title_column/db_schema.xml @@ -10,7 +10,7 @@ <table name="test_table" resource="default" comment="Test Table"> <column xsi:type="int" name="page_id" nullable="false" /> <column xsi:type="varchar" name="email" nullable="false" /> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id" /> <column name="email" /> </constraint> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/restore_title_column/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/restore_title_column/db_schema.xml index 4520cd9e4d406..8082157524ad4 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/restore_title_column/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule4/revisions/restore_title_column/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="int" name="page_id" nullable="false" /> <column xsi:type="varchar" name="email" nullable="false" /> <column xsi:type="varchar" name="title" /> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id" /> <column name="email" /> </constraint> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml index b6ff634e6ef1d..9bd6c438455b2 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="tinyint" name="tinyint_ref" padding="7" nullable="false" identity="true" unsigned="false"/> <column xsi:type="int" name="some_integer" default="0" nullable="false" unsigned="false"/> <column xsi:type="varchar" name="for_patch_testing" comment="For patch testing" /> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> </constraint> </table> @@ -21,10 +21,10 @@ <column xsi:type="tinyint" name="tinyint" padding="7" nullable="true" unsigned="false"/> <column xsi:type="varchar" name="varchar" length="254" nullable="true"/> <column xsi:type="varbinary" name="varbinary" default="10101" /> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="CASCADE"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="smallint" /> </constraint> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml index 9263004c6e7f6..d6be9376cb4da 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml @@ -21,7 +21,7 @@ <column xsi:type="bigint" name="bigint_default_nullable" padding="2" nullable="true" default="1" unsigned="true"/> <column xsi:type="bigint" name="bigint_not_default_not_nullable" padding="2" nullable="false" unsigned="true"/> - <constraint xsi:type="primary" name="tinyint_primary"> + <constraint xsi:type="primary" referenceId="tinyint_primary"> <column name="tinyint_ref"/> </constraint> </table> @@ -30,7 +30,7 @@ nullable="true"/> <column xsi:type="smallint" name="int_disabled_auto_increment" default="0" identity="false" padding="12" unsigned="true" nullable="true"/> - <constraint xsi:type="unique" name="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> + <constraint xsi:type="unique" referenceId="AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE"> <column name="int_auto_increment_with_nullable"/> </constraint> </table> @@ -53,15 +53,15 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" name="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" name="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index name="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/incosistence_reference_definition/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/incosistence_reference_definition/db_schema.xml index e39f0a04bcf5f..1b7d0dcb93ce7 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/incosistence_reference_definition/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/incosistence_reference_definition/db_schema.xml @@ -9,13 +9,13 @@ xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="test_table" resource="default" comment="Test Table"> <column xsi:type="int" name="page_id" nullable="false" unsigned="false" identity="true"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id"/> </constraint> </table> <table name="dependent" resource="default" comment="Lol"> <column xsi:type="int" name="page_id_on" nullable="true" unsigned="true"/> - <constraint xsi:type="foreign" name="FOREIGN" table="dependent" column="page_id_on" referenceColumn="page_id" + <constraint xsi:type="foreign" referenceId="FOREIGN" table="dependent" column="page_id_on" referenceColumn="page_id" referenceTable="test_table"/> </table> </schema> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/invalid_primary_key/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/invalid_primary_key/db_schema.xml index 4ecee62286418..b42d74aea06a1 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/invalid_primary_key/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/invalid_primary_key/db_schema.xml @@ -11,7 +11,7 @@ <column xsi:type="int" name="page_id" nullable="false" identity="true" /> <column xsi:type="varchar" name="email" nullable="true" /> <column xsi:type="varchar" name="title" /> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="page_id" /> <column name="email" /> </constraint> From 456b72e7be3b11d129300651668850442df113ad Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Fri, 19 Oct 2018 11:40:38 -0500 Subject: [PATCH 387/812] MAGETWO-95002: [GraphQL] Product search do not work with elasticsearch --- .../CatalogGraphQl/Model/Resolver/Products/Query/Search.php | 2 +- app/code/Magento/GraphQl/Controller/GraphQl.php | 1 - app/code/Magento/Search/Model/Search/PageSizeProvider.php | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) 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 80d65e96625e8..f9b64f3a3c69b 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/Search.php @@ -45,7 +45,7 @@ class Search private $metadataPool; /** - * @var \Magento\CatalogSearch\Model\Search\PageSizeProvider + * @var \Magento\Search\Model\Search\PageSizeProvider */ private $pageSizeProvider; diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php index d957f394ee714..c4a0b55de9bfc 100644 --- a/app/code/Magento/GraphQl/Controller/GraphQl.php +++ b/app/code/Magento/GraphQl/Controller/GraphQl.php @@ -108,7 +108,6 @@ public function dispatch(RequestInterface $request) : ResponseInterface try { /** @var Http $request */ $this->requestProcessor->processHeaders($request); - $data = $this->jsonSerializer->unserialize($request->getContent()); $query = isset($data['query']) ? $data['query'] : ''; diff --git a/app/code/Magento/Search/Model/Search/PageSizeProvider.php b/app/code/Magento/Search/Model/Search/PageSizeProvider.php index 43e20aae8e697..5572bac6addc3 100644 --- a/app/code/Magento/Search/Model/Search/PageSizeProvider.php +++ b/app/code/Magento/Search/Model/Search/PageSizeProvider.php @@ -9,6 +9,7 @@ /** * Returns max page size by search engine name + * @api */ class PageSizeProvider { From c366d477010c08e2c9ffdbe09edcd61b1082efa2 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 19 Oct 2018 19:59:59 +0300 Subject: [PATCH 388/812] GraphQL-174: Absolute image paths for Products --- .../Resolver/Product/ProductImage/Label.php | 27 ++++++++++++------- .../Resolver/Product/ProductImage/Url.php | 4 +-- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php index 5b752e7184893..e9020c2df5333 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php @@ -62,24 +62,33 @@ public function resolve( /** @var Product $product */ $product = $value['model']; + $imageType = $value['image_type']; + $imagePath = $product->getData($imageType); + $productId = (int)$product->getEntityId(); + + // null if image is not set + if (null === $imagePath) { + return $this->getAttributeValue($productId, 'name'); + } + + $imageLabel = $this->getAttributeValue($productId, $imageType . '_label'); + if (null === $imageLabel) { + $imageLabel = $this->getAttributeValue($productId, 'name'); + } - $imageLabel = $this->getImageLabel((int)$product->getEntityId(), $value['image_type']); return $imageLabel; } /** * @param int $productId - * @param string $imageType - * @return string + * @param string $attributeCode + * @return null|string Null if attribute value is not exists */ - private function getImageLabel(int $productId, string $imageType): string + private function getAttributeValue(int $productId, string $attributeCode): ?string { $storeId = $this->storeManager->getStore()->getId(); - $imageLabel = $this->productResource->getAttributeRawValue($productId, $imageType . '_label', $storeId); - if (empty($imageLabel)) { - $imageLabel = $this->productResource->getAttributeRawValue($productId, 'name', $storeId); - } - return $imageLabel; + $value = $this->productResource->getAttributeRawValue($productId, $attributeCode, $storeId); + return is_array($value) && empty($value) ? null : $value; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php index d9136e742b178..c6659080ee9e9 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php @@ -61,10 +61,10 @@ public function resolve( /** * @param string $imageType - * @param string $imagePath + * @param string|null $imagePath Null if image is not set * @return string */ - private function getImageUrl(string $imageType, string $imagePath): string + private function getImageUrl(string $imageType, ?string $imagePath): string { $image = $this->productImageFactory->create(); $image->setDestinationSubdir($imageType) From bc4800a0ae383ab5043078cf6e9c14608cb0b44d Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@adobe.com> Date: Fri, 19 Oct 2018 12:13:12 -0500 Subject: [PATCH 389/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../unpatterned_fk_name/db_schema.xml | 32 +++++++++++++++++++ dev/tests/setup-integration/phpunit.xml.dist | 6 ++-- .../Setup/DeclarativeInstallerTest.php | 21 ++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml new file mode 100644 index 0000000000000..f5b6d13c3cbe4 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="test_table" resource="default" comment="Test Table"> + <column xsi:type="int" name="page_id" nullable="false" unsigned="false" identity="true"/> + <constraint xsi:type="primary" referenceId="PRIMARY"> + <column name="page_id"/> + </constraint> + </table> + <table name="test_scope_table" resource="default" comment="Test Scope Table"> + <column xsi:type="int" name="scope_id" nullable="false" unsigned="false" identity="true"/> + <constraint xsi:type="primary" referenceId="PRIMARY"> + <column name="scope_id"/> + </constraint> + </table> + <table name="dependent" resource="default" comment="Lol"> + <column xsi:type="int" name="page_id_on" nullable="false" unsigned="false"/> + <column xsi:type="int" name="scope_id_on" nullable="false" unsigned="false"/> + <!-- Expected name in DB: DEPENDENT_PAGE_ID_ON_TEST_TABLE_PAGE_ID --> + <constraint xsi:type="foreign" referenceId="FOREIGN" table="dependent" column="page_id_on" referenceColumn="page_id" + referenceTable="test_table"/> + <!-- Expected name in DB: DEPENDENT_SCOPE_ID_ON_TEST_SCOPE_TABLE_SCOPE_ID --> + <constraint xsi:type="foreign" referenceId="ScopeIDOnTOScopeTableAndScopeId" table="dependent" column="scope_id_on" referenceColumn="scope_id" + referenceTable="test_scope_table"/> + </table> +</schema> diff --git a/dev/tests/setup-integration/phpunit.xml.dist b/dev/tests/setup-integration/phpunit.xml.dist index 7dd8609bdcadf..04f8872557e58 100644 --- a/dev/tests/setup-integration/phpunit.xml.dist +++ b/dev/tests/setup-integration/phpunit.xml.dist @@ -32,11 +32,11 @@ <includePath>testsuite</includePath> <ini name="date.timezone" value="America/Los_Angeles"/> <ini name="xdebug.max_nesting_level" value="200"/> - <const name="TESTS_INSTALL_CONFIG_FILE" value="{{local_config_file}}"/> + <const name="TESTS_INSTALL_CONFIG_FILE" value="etc/install-config-mysql.php"/> <const name="TESTS_GLOBAL_CONFIG_FILE" value="etc/config-global.php"/> <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> - <const name="TESTS_CLEANUP" value="{{tests_cleanup}}"/> - <const name="TESTS_MAGENTO_MODE" value="{{app_mode}}"/> + <const name="TESTS_CLEANUP" value="enabled"/> + <const name="TESTS_MAGENTO_MODE" value="developer"/> <const name="TESTS_ERROR_LOG_LISTENER_LEVEL" value="1"/> </php> <!-- Test listeners --> diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php index 34d432e566fec..33f4b170637c2 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php @@ -296,4 +296,25 @@ public function testTableRename() ->from($this->resourceConnection->getTableName('some_table_renamed')); self::assertEquals([$dataToMigrate], $adapter->fetchAll($select)); } + + /** + * @moduleName Magento_TestSetupDeclarationModule8 + */ + public function testForeignKeyReferenceId() + { + $this->cliCommad->install( + ['Magento_TestSetupDeclarationModule8'] + ); + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule8', + 'unpatterned_fk_name', + 'db_schema.xml', + 'etc' + ); + $this->cliCommad->upgrade(); + $tableStatements = $this->describeTable->describeShard('default'); + $tableSql = $tableStatements['dependent']; + $this->assertRegExp('/CONSTRAINT\s`DEPENDENT_PAGE_ID_ON_TEST_TABLE_PAGE_ID`/', $tableSql); + $this->assertRegExp('/CONSTRAINT\s`DEPENDENT_SCOPE_ID_ON_TEST_SCOPE_TABLE_SCOPE_ID`/', $tableSql); + } } From ff756d7ce6aa201017997ec9e4c16f64ca90021a Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@adobe.com> Date: Fri, 19 Oct 2018 12:44:56 -0500 Subject: [PATCH 390/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../revisions/unpatterned_fk_name/db_schema.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml index f5b6d13c3cbe4..eebeb154adf43 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/unpatterned_fk_name/db_schema.xml @@ -23,7 +23,7 @@ <column xsi:type="int" name="page_id_on" nullable="false" unsigned="false"/> <column xsi:type="int" name="scope_id_on" nullable="false" unsigned="false"/> <!-- Expected name in DB: DEPENDENT_PAGE_ID_ON_TEST_TABLE_PAGE_ID --> - <constraint xsi:type="foreign" referenceId="FOREIGN" table="dependent" column="page_id_on" referenceColumn="page_id" + <constraint xsi:type="foreign" referenceId="DEPENDENT_PAGE_ID_ON_TEST_TABLE_PAGE_ID" table="dependent" column="page_id_on" referenceColumn="page_id" referenceTable="test_table"/> <!-- Expected name in DB: DEPENDENT_SCOPE_ID_ON_TEST_SCOPE_TABLE_SCOPE_ID --> <constraint xsi:type="foreign" referenceId="ScopeIDOnTOScopeTableAndScopeId" table="dependent" column="scope_id_on" referenceColumn="scope_id" From 909d777526fed8378b33f08a99e2935d34dce9ab Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@adobe.com> Date: Fri, 19 Oct 2018 12:46:42 -0500 Subject: [PATCH 391/812] MAGETWO-95595: Index names are ignored by declarative schema --- dev/tests/setup-integration/phpunit.xml.dist | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/setup-integration/phpunit.xml.dist b/dev/tests/setup-integration/phpunit.xml.dist index 04f8872557e58..7dd8609bdcadf 100644 --- a/dev/tests/setup-integration/phpunit.xml.dist +++ b/dev/tests/setup-integration/phpunit.xml.dist @@ -32,11 +32,11 @@ <includePath>testsuite</includePath> <ini name="date.timezone" value="America/Los_Angeles"/> <ini name="xdebug.max_nesting_level" value="200"/> - <const name="TESTS_INSTALL_CONFIG_FILE" value="etc/install-config-mysql.php"/> + <const name="TESTS_INSTALL_CONFIG_FILE" value="{{local_config_file}}"/> <const name="TESTS_GLOBAL_CONFIG_FILE" value="etc/config-global.php"/> <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> - <const name="TESTS_CLEANUP" value="enabled"/> - <const name="TESTS_MAGENTO_MODE" value="developer"/> + <const name="TESTS_CLEANUP" value="{{tests_cleanup}}"/> + <const name="TESTS_MAGENTO_MODE" value="{{app_mode}}"/> <const name="TESTS_ERROR_LOG_LISTENER_LEVEL" value="1"/> </php> <!-- Test listeners --> From 228660dea739c63288a26e3a8de431e8f1a5f44d Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Fri, 19 Oct 2018 21:07:16 +0300 Subject: [PATCH 392/812] Cover \Magento\Email\Model\Template\SenderResolver class with Unit test --- .../Model/Template/SenderResolverTest.php | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 app/code/Magento/Email/Test/Unit/Model/Template/SenderResolverTest.php diff --git a/app/code/Magento/Email/Test/Unit/Model/Template/SenderResolverTest.php b/app/code/Magento/Email/Test/Unit/Model/Template/SenderResolverTest.php new file mode 100644 index 0000000000000..fb25290f9d27b --- /dev/null +++ b/app/code/Magento/Email/Test/Unit/Model/Template/SenderResolverTest.php @@ -0,0 +1,112 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Email\Test\Unit\Model\Template; + +use Magento\Email\Model\Template\SenderResolver; +use Magento\Framework\Exception\MailException; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\App\Config\ScopeConfigInterface; + +/** + * SenderResolverTest + */ +class SenderResolverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var SenderResolver + */ + private $senderResolver; + + /** + * @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $scopeConfig; + + /** + * @return void + */ + public function setUp(): void + { + $objectManager = new ObjectManager($this); + + $this->scopeConfig = $this->createMock(ScopeConfigInterface::class); + + $this->senderResolver = $objectManager->getObject( + SenderResolver::class, + [ + 'scopeConfig' => $this->scopeConfig + ] + ); + } + + /** + * Test returned information for given sender's name and email + * + * @return void + */ + public function testResolve(): void + { + $sender = 'general'; + $scopeId = null; + + $this->scopeConfig->expects($this->exactly(2)) + ->method('getValue') + ->willReturnMap([ + [ + 'trans_email/ident_' . $sender . '/name', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $scopeId, + 'Test Name' + ], + [ + 'trans_email/ident_' . $sender . '/email', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $scopeId, + 'test@email.com' + ] + ]); + + $result = $this->senderResolver->resolve($sender); + + $this->assertTrue(isset($result['name'])); + $this->assertEquals('Test Name', $result['name']); + + $this->assertTrue(isset($result['email'])); + $this->assertEquals('test@email.com', $result['email']); + } + + /** + * Test if exception is thrown in case there is no name or email in result + * + * @dataProvider dataProvidedSenderArray + * @param array $sender + * + * @return void + */ + public function testResolveThrowException(array $sender): void + { + $this->expectExceptionMessage('Invalid sender data'); + $this->expectException(MailException::class); + $this->senderResolver->resolve($sender); + } + + /** + * @return array + */ + public function dataProvidedSenderArray() + { + return [ + [ + ['name' => 'Name'] + ], + [ + ['email' => 'test@email.com'] + ] + ]; + } +} From 1872979e49cb60dd7ea3927dddd9a19ff29d52d3 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Fri, 19 Oct 2018 09:51:12 +0300 Subject: [PATCH 393/812] Added Unit Test for WindowsSmtpConfig Plugin --- .../Model/Plugin/WindowsSmtpConfigTest.php | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 app/code/Magento/Email/Test/Unit/Model/Plugin/WindowsSmtpConfigTest.php diff --git a/app/code/Magento/Email/Test/Unit/Model/Plugin/WindowsSmtpConfigTest.php b/app/code/Magento/Email/Test/Unit/Model/Plugin/WindowsSmtpConfigTest.php new file mode 100644 index 0000000000000..5f7c44b988c66 --- /dev/null +++ b/app/code/Magento/Email/Test/Unit/Model/Plugin/WindowsSmtpConfigTest.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Email\Test\Unit\Model\Plugin; + +use Magento\Email\Model\Plugin\WindowsSmtpConfig; +use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\Framework\Mail\TransportInterface; +use Magento\Framework\OsInfo; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +/** + * WindowsSmtpConfigTest + */ +class WindowsSmtpConfigTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var WindowsSmtpConfig + */ + private $windowsSmtpConfig; + + /** + * @var OsInfo|\PHPUnit_Framework_MockObject_MockObject + */ + private $osInfoMock; + + /** + * @var ReinitableConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $configMock; + + /** + * @var TransportInterface + */ + private $transportMock; + + /** + * setUp + * + * @return void + */ + public function setUp(): void + { + $objectManager = new ObjectManager($this); + + $this->osInfoMock = $this->createMock(OsInfo::class); + $this->configMock = $this->createMock(ReinitableConfigInterface::class); + $this->transportMock = $this->createMock(TransportInterface::class); + + $this->windowsSmtpConfig = $objectManager->getObject( + WindowsSmtpConfig::class, + [ + 'config' => $this->configMock, + 'osInfo' => $this->osInfoMock + ] + ); + } + + /** + * Test if SMTP settings if windows server + * + * @return void + */ + public function testBeforeSendMessageOsWindows(): void + { + $this->osInfoMock->expects($this->once()) + ->method('isWindows') + ->willReturn(true); + + $this->configMock->expects($this->exactly(2)) + ->method('getValue') + ->willReturnMap([ + [WindowsSmtpConfig::XML_SMTP_HOST, '127.0.0.1'], + [WindowsSmtpConfig::XML_SMTP_PORT, '80'] + ]); + + $this->windowsSmtpConfig->beforeSendMessage($this->transportMock); + } + + /** + * Test if SMTP settings if not windows server + * + * @return void + */ + public function testBeforeSendMessageOsIsWindows(): void + { + $this->osInfoMock->expects($this->once()) + ->method('isWindows') + ->willReturn(false); + + $this->configMock->expects($this->never()) + ->method('getValue'); + + $this->windowsSmtpConfig->beforeSendMessage($this->transportMock); + } +} From fef2205724afcacfa8b9b4243a228d5b37c0f395 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <okorshenko@magento.com> Date: Fri, 19 Oct 2018 13:30:11 -0500 Subject: [PATCH 394/812] Issue magento/magento2#17830: Add checkout_cart_product_add_before event - fixed broken unit test --- app/code/Magento/Checkout/Test/Unit/Model/CartTest.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php b/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php index a862fbb1306e9..bc66324c2986d 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php @@ -370,7 +370,7 @@ public function testAddProductException() ->method('getById') ->will($this->returnValue($product)); - $this->eventManagerMock->expects($this->at(0))->method('dispatch')->with( + $this->eventManagerMock->expects($this->once())->method('dispatch')->with( 'checkout_cart_product_add_before', ['info' => 4, 'product' => $product] ); @@ -382,10 +382,6 @@ public function testAddProductException() ->method('getQuote') ->will($this->returnValue($this->quoteMock)); - $this->eventManagerMock->expects($this->never())->method('dispatch')->with( - 'checkout_cart_product_add_after', - ['quote_item' => 1, 'product' => $product] - ); $this->expectException(\Magento\Framework\Exception\LocalizedException::class); $this->cart->addProduct(4, 4); } From 0de795a668d63b89327b19cc8df43e97ee4a7cf7 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <korshenk@adobe.com> Date: Fri, 19 Oct 2018 13:37:30 -0500 Subject: [PATCH 395/812] Issue magento/magento2#17830: Add checkout_cart_product_add_before event - fixed broken static test --- app/code/Magento/Checkout/Model/Cart.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Checkout/Model/Cart.php b/app/code/Magento/Checkout/Model/Cart.php index c43adde2f192a..eff07af0e6a3e 100644 --- a/app/code/Magento/Checkout/Model/Cart.php +++ b/app/code/Magento/Checkout/Model/Cart.php @@ -619,6 +619,8 @@ public function truncate() } /** + * Get product ids. + * * @return int[] */ public function getProductIds() From 2064e2417b53232257a4a49db18980f0d0c34d12 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Fri, 19 Oct 2018 22:03:15 +0300 Subject: [PATCH 396/812] Cover \Magento\GiftMessage\Observer\SalesEventQuoteMerge with Unit test --- .../Observer/SalesEventQuoteMergeTest.php | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php diff --git a/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php b/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php new file mode 100644 index 0000000000000..f82bc01c485e9 --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php @@ -0,0 +1,81 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\GiftMessage\Test\Unit\Observer; + +use Magento\GiftMessage\Observer\SalesEventQuoteMerge; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use \Magento\Framework\Event\Observer; +use Magento\Quote\Model\Quote; + +/** + * SalesEventQuoteMergeTest + */ +class SalesEventQuoteMergeTest extends \PHPUnit\Framework\TestCase +{ + + /** + * @var SalesEventQuoteMerge + */ + private $salesEventQuoteMerge; + + /** + * @return void + */ + public function setUp(): void + { + $objectManger = new ObjectManager($this); + $this->salesEventQuoteMerge = $objectManger->getObject(SalesEventQuoteMerge::class); + } + + /** + * @dataProvider dataProviderGiftMessageId + * + * @param null|int $giftMessageId + * + * @return void + */ + public function testExecute($giftMessageId): void + { + $sourceQuoteMock = $this->createPartialMock(Quote::class, ['getGiftMessageId']); + $sourceQuoteMock->expects($this->once()) + ->method('getGiftMessageId') + ->willReturn($giftMessageId); + + $targetQuoteMock = $this->createPartialMock(Quote::class, ['setGiftMessageId']); + + if ($giftMessageId) { + $targetQuoteMock->expects($this->once()) + ->method('setGiftMessageId'); + } else { + $targetQuoteMock->expects($this->never()) + ->method('setGiftMessageId'); + } + + $observer = $this->createMock(Observer::class); + $observer->expects($this->exactly(2)) + ->method('getData') + ->willReturnMap([ + ['quote', null, $targetQuoteMock], + ['source', null, $sourceQuoteMock] + ]); + + $this->salesEventQuoteMerge->execute($observer); + } + + /** + * @return array + */ + public function dataProviderGiftMessageId(): array + { + return [ + [null], + [1] + ]; + } +} From 860afbb9256608426cf024f114182b7b10ce59bb Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Fri, 19 Oct 2018 22:11:32 +0300 Subject: [PATCH 397/812] Covering the CategoryProductIndexer by Unit Test --- .../Observer/CategoryProductIndexerTest.php | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 app/code/Magento/Elasticsearch/Test/Unit/Observer/CategoryProductIndexerTest.php diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Observer/CategoryProductIndexerTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Observer/CategoryProductIndexerTest.php new file mode 100644 index 0000000000000..adebee0d591ab --- /dev/null +++ b/app/code/Magento/Elasticsearch/Test/Unit/Observer/CategoryProductIndexerTest.php @@ -0,0 +1,136 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Elasticsearch\Test\Unit\Observer; + +use Magento\CatalogSearch\Model\Indexer\Fulltext\Processor; +use Magento\Elasticsearch\Model\Config; +use Magento\Elasticsearch\Observer\CategoryProductIndexer; +use Magento\Framework\Event; +use Magento\Framework\Event\Observer; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +/** + * Class CategoryProductIndexerTest + */ +class CategoryProductIndexerTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var CategoryProductIndexer + */ + private $observer; + + /** + * @var Config|\PHPUnit_Framework_MockObject_MockObject + */ + private $configMock; + + /** + * @var Processor|\PHPUnit_Framework_MockObject_MockObject + */ + private $processorMock; + + /** + * @var Observer|\PHPUnit_Framework_MockObject_MockObject + */ + private $observerMock; + + /** + * Set Up method + * + * @return void + */ + protected function setUp(): void + { + $this->configMock = $this->createMock(Config::class); + $this->processorMock = $this->createMock(Processor::class); + $this->observerMock = $this->createMock(Observer::class); + + $objectManager = new ObjectManagerHelper($this); + $this->observer = $objectManager->getObject( + CategoryProductIndexer::class, + [ + 'config' => $this->configMock, + 'processor' => $this->processorMock, + ] + ); + } + + /** + * Test if a category has changed products + * + * @return void + */ + public function testExecuteIfCategoryHasChangedProducts() + { + $this->getProductIdsWithEnabledElasticSearch(); + $this->processorMock->expects($this->once())->method('isIndexerScheduled')->willReturn(true); + $this->processorMock->expects($this->once())->method('markIndexerAsInvalid'); + $this->observer->execute($this->observerMock); + } + + /** + * Test if a category has changed products and not scheduled indexer + * + * @return void + */ + public function testExecuteIfCategoryHasChangedProductsAndNotScheduledIndexer(): void + { + $this->getProductIdsWithEnabledElasticSearch(); + $this->processorMock->expects($this->once())->method('isIndexerScheduled')->willReturn(false); + $this->processorMock->expects($this->never())->method('markIndexerAsInvalid'); + $this->observer->execute($this->observerMock); + } + + /** + * Test if a category has none changed products + * + * @return void + */ + public function testExecuteIfCategoryHasNoneChangedProducts(): void + { + /** @var Event|\PHPUnit_Framework_MockObject_MockObject $eventMock */ + $eventMock = $this->createPartialMock(Event::class, ['getProductIds']); + $this->configMock->expects($this->once())->method('isElasticsearchEnabled')->willReturn(true); + + $eventMock->expects($this->once())->method('getProductIds')->willReturn([]); + $this->observerMock->expects($this->once())->method('getEvent')->willReturn($eventMock); + + $this->processorMock->expects($this->never())->method('isIndexerScheduled'); + $this->processorMock->expects($this->never())->method('markIndexerAsInvalid'); + + $this->observer->execute($this->observerMock); + } + + /** + * Test if ElasticSearch is disabled + * + * @return void + */ + public function testExecuteIfElasticSearchIsDisabled(): void + { + /** @var Event|\PHPUnit_Framework_MockObject_MockObject $eventMock */ + $eventMock = $this->createPartialMock(Event::class, ['getProductIds']); + $this->configMock->expects($this->once())->method('isElasticsearchEnabled')->willReturn(false); + $eventMock->expects($this->never())->method('getProductIds')->willReturn([]); + $this->observer->execute($this->observerMock); + } + + /** + * Get product ids with enabled ElasticSearch + * + * @return void + */ + private function getProductIdsWithEnabledElasticSearch(): void + { + /** @var Event|\PHPUnit_Framework_MockObject_MockObject $eventMock */ + $eventMock = $this->createPartialMock(Event::class, ['getProductIds']); + $this->configMock->expects($this->once())->method('isElasticsearchEnabled')->willReturn(true); + $eventMock->expects($this->once())->method('getProductIds')->willReturn([1]); + $this->observerMock->expects($this->once())->method('getEvent')->willReturn($eventMock); + } +} From 8bd8b4dc938d1a2516dc3dc1084c0e29279fbddb Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 19 Oct 2018 15:10:24 -0500 Subject: [PATCH 398/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../foreign_key_interpreter_result.php | 2 +- .../fixture/valid_xml_revision_1.php | 10 +++---- .../Setup/DeclarativeInstallerTest.php | 26 +++++++++++++++---- .../Definition/Constraints/ForeignKey.php | 2 +- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php index 76fcf6b2fad11..e3068c1bd7625 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php @@ -33,7 +33,7 @@ 'constraint' => [ 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF' => [ 'type' => 'foreign', - 'name' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', + 'referenceId' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', 'column' => 'tinyint', 'table' => 'test_table', 'referenceTable' => 'reference_table', diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php index cd42a1e8fc360..7271103e3e721 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php @@ -93,7 +93,7 @@ 'tinyint_ref' => 'tinyint_ref', ], 'type' => 'primary', - 'name' => 'tinyint_primary', + 'referenceId' => 'tinyint_primary', ], ], 'name' => 'reference_table', @@ -125,7 +125,7 @@ 'int_auto_increment_with_nullable' => 'int_auto_increment_with_nullable', ], 'type' => 'unique', - 'name' => 'AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE', + 'referenceId' => 'AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE', ], ], 'name' => 'auto_increment_test', @@ -231,11 +231,11 @@ 'bigint' => 'bigint', ], 'type' => 'unique', - 'name' => 'TEST_TABLE_SMALLINT_BIGINT', + 'referenceId' => 'TEST_TABLE_SMALLINT_BIGINT', ], 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF' => [ 'type' => 'foreign', - 'name' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', + 'referenceId' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', 'column' => 'tinyint', 'table' => 'test_table', 'referenceTable' => 'reference_table', @@ -249,7 +249,7 @@ 'tinyint' => 'tinyint', 'bigint' => 'bigint', ], - 'name' => 'TEST_TABLE_TINYINT_BIGINT', + 'referenceId' => 'TEST_TABLE_TINYINT_BIGINT', 'indexType' => 'btree', ], ], diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php index 34d432e566fec..856bdde4e98f3 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php @@ -79,8 +79,26 @@ public function testInstallation() //Second time installation should not find anything as we do not change anything self::assertNull($diff->getAll()); + $this->compareStructures(); + } + + /** + * Compare structure of DB and declared structure. + */ + private function compareStructures() + { $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getTrimmedData(), $shardData); + foreach ($this->getTrimmedData() as $tableName => $sql) { + $this->assertArrayHasKey($tableName, $shardData); + /** + * MySQL 8.0 and above does not provide information about the ON DELETE instruction + * if ON DELETE NO ACTION + */ + if (preg_match('#ON DELETE\s+NO ACTION#i', $shardData[$tableName] === 1)) { + preg_replace('#ON DELETE\s+NO ACTION#i', '', $sql); + self::assertEquals($sql, $shardData[$tableName]); + } + } } /** @@ -110,8 +128,7 @@ public function testInstallationWithColumnsModification() $this->schemaConfig->getDbConfig() ); self::assertNull($diff->getAll()); - $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getTrimmedData(), $shardData); + $this->compareStructures(); } /** @@ -156,8 +173,7 @@ public function testInstallationWithColumnsRemoval() $this->schemaConfig->getDbConfig() ); self::assertNull($diff->getAll()); - $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getTrimmedData(), $shardData); + $this->compareStructures(); } /** diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php index 1a9b42355f5e2..26bc2209d01ec 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php @@ -95,7 +95,7 @@ public function fromDefinition(array $data) 'column' => $match[2], 'referenceTable' => $match[5], 'referenceColumn' => $match[6], - 'onDelete' => isset($match[7]) ? $match[8] : '' + 'onDelete' => isset($match[7]) ? $match[8] : 'NO ACTION' ]; } } From e5539b4bcac7329f4248a02a6e7a8fa646e6654c Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Fri, 19 Oct 2018 15:35:55 -0500 Subject: [PATCH 399/812] MAGETWO-95161: Layered Navigation Price step field displays as Mandatory but user can save categories by leaving the field empty. - added functional test to cover the bug fix --- .../AdminCategoryBasicFieldSection.xml | 7 +++++ .../Mftf/Test/AdminCreateCategoryTest.xml | 30 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryBasicFieldSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryBasicFieldSection.xml index 8b69a44993f17..9a0dd8f5b387d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryBasicFieldSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryBasicFieldSection.xml @@ -32,6 +32,13 @@ <element name="DesignTab" type="button" selector="//strong[@class='admin__collapsible-title']//span[text()='Design']"/> <element name="LayoutDropdown" type="select" selector="select[name='page_layout']"/> </section> + <section name="CategoryDisplaySettingsSection"> + <element name="DisplaySettingTab" type="button" selector="//strong[@class='admin__collapsible-title']//span[text()='Display Settings']"/> + <element name="layeredNavigationPriceInput" type="input" selector="input[name='filter_price_range']"/> + <element name="FieldError" type="text" selector=".admin__field-error[data-bind='attr: {for: {{field}}}, text: error']" parameterized="true"/> + <element name="filterPriceRangeUseConfig" type="checkbox" selector="input[name='use_config[filter_price_range]']"/> + <element name="RequiredFieldIndicator" type="text" selector=" return window.getComputedStyle(document.querySelector('._required[data-index={{arg1}}]>.admin__field-label span'), ':after').getPropertyValue('content');" parameterized="true"/> + </section> <section name="CatalogWYSIWYGSection"> <element name="ShowHideBtn" type="button" selector="#togglecategory_form_description"/> <element name="TinyMCE4" type="text" selector=".mce-branding-powered-by"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml index bfb9557910642..057a551e1e46a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml @@ -69,4 +69,34 @@ <waitForElementVisible selector="{{CategoryDesignSection.LayoutDropdown}}" stepKey="waitForLayoutDropDown" /> <seeOptionIsSelected selector="{{CategoryDesignSection.LayoutDropdown}}" userInput="2 columns with right bar" stepKey="see2ColumnsSelected" /> </test> + <test name="AdminCategoryFormDisplaySettingsUIValidationTest"> + <annotations> + <features value="Catalog"/> + <stories value="Default layout configuration MAGETWO-88793"/> + <title value="Category should not be saved once layered navigation price step field is left empty"/> + <description value="Once the Config setting is unchecked Category should not be saved with layered navigation price field left empty"/> + <severity value="AVERAGE"/> + <testCaseId value="MAGETWO-95797"/> + <group value="category"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage"/> + <waitForPageLoad time="30" stepKey="waitForPageLoad1"/> + <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategory"/> + <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{SimpleSubCategory.name}}" stepKey="enterCategoryName"/> + <click selector="{{CategoryDisplaySettingsSection.DisplaySettingTab}}" stepKey="clickOnDisplaySettingsTab"/> + <waitForElementVisible selector="{{CategoryDisplaySettingsSection.filterPriceRangeUseConfig}}" stepKey="wait"/> + <scrollTo selector="{{CategoryDisplaySettingsSection.layeredNavigationPriceInput}}" stepKey="scrollToLayeredNavigationField"/> + <uncheckOption selector="{{CategoryDisplaySettingsSection.filterPriceRangeUseConfig}}" stepKey="uncheckConfigSetting"/> + <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> + <see selector="{{AdminCategoryBasicFieldSection.FieldError('uid')}}" userInput="This is a required field." stepKey="seeErrorMessage"/> + <!-- Verify that the Layered navigation price step field has the required indicator --> + <executeJS function="{{CategoryDisplaySettingsSection.RequiredFieldIndicator('filter_price_range')}}" stepKey="getRequiredFieldIndicator"/> + <assertEquals expected='"*"' expectedType="string" actualType="variable" actual="getRequiredFieldIndicator" message="pass" stepKey="assertRequiredFieldIndicator1"/> + </test> </tests> From 0a253644a43f39d8ab40701011512534f4fc34bb Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Fri, 19 Oct 2018 23:39:54 +0300 Subject: [PATCH 400/812] Fixed issue #4468 "Unable to insert multiple catalog product list widgets (with pager) in CMS page" --- .../Block/Product/ProductsList.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index 5b9905e0c9d81..a0cfc08406189 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -198,7 +198,7 @@ public function getProductPriceHtml( ? $arguments['display_minimal_price'] : true; - /** @var \Magento\Framework\Pricing\Render $priceRender */ + /** @var \Magento\Framework\Pricing\Render $priceRender */ $priceRender = $this->getLayout()->getBlock('product.price.render.default'); if (!$priceRender) { $priceRender = $this->getLayout()->createBlock( @@ -347,7 +347,7 @@ public function getPagerHtml() if (!$this->pager) { $this->pager = $this->getLayout()->createBlock( \Magento\Catalog\Block\Product\Widget\Html\Pager::class, - 'widget.products.list.pager' + $this->getWidgetPagerBlockName() ); $this->pager->setUseContainer(true) @@ -408,4 +408,19 @@ private function getPriceCurrency() } return $this->priceCurrency; } + + /** + * @return string + */ + private function getWidgetPagerBlockName() + { + $pageName = $this->getData('page_var_name'); + $pagerBlockName = 'widget.products.list.pager'; + + if (!$pageName) { + return $pagerBlockName; + } + + return $pagerBlockName . '.' . $pageName; + } } From efc348b2c90bd12d5184f6f9f7d5abb4b9ba8564 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Fri, 19 Oct 2018 16:18:58 -0500 Subject: [PATCH 401/812] MAGETWO-95161: Layered Navigation Price step field displays as Mandatory but user can save categories by leaving the field empty. - addressing CR comments --- .../Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml index 057a551e1e46a..8806612c0f5de 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml @@ -82,9 +82,9 @@ <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> - <after> - <actionGroup ref="logout" stepKey="logout"/> - </after> + <after> + <actionGroup ref="logout" stepKey="logout"/> + </after> <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage"/> <waitForPageLoad time="30" stepKey="waitForPageLoad1"/> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategory"/> @@ -96,6 +96,7 @@ <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategory"/> <see selector="{{AdminCategoryBasicFieldSection.FieldError('uid')}}" userInput="This is a required field." stepKey="seeErrorMessage"/> <!-- Verify that the Layered navigation price step field has the required indicator --> + <comment userInput="Check if Layered navigation price field has required indictor icon" stepKey="comment" /> <executeJS function="{{CategoryDisplaySettingsSection.RequiredFieldIndicator('filter_price_range')}}" stepKey="getRequiredFieldIndicator"/> <assertEquals expected='"*"' expectedType="string" actualType="variable" actual="getRequiredFieldIndicator" message="pass" stepKey="assertRequiredFieldIndicator1"/> </test> From 5df1c200106f2794a0f3a23692628197a3cb6fbd Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 19 Oct 2018 17:13:48 -0500 Subject: [PATCH 402/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../TablesWhitelistGenerateCommand.php | 72 +++++++++++++------ .../etc/db_schema.xml | 6 +- .../TablesWhitelistGenerateCommandTest.php | 2 + 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php index b30edc0c7976f..1832cfce7f158 100644 --- a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php +++ b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php @@ -10,7 +10,10 @@ use Magento\Framework\Component\ComponentRegistrar; use Magento\Framework\Config\FileResolverByModule; use Magento\Framework\Module\Dir; +use Magento\Framework\Setup\Declaration\Schema\Declaration\SchemaBuilder; use Magento\Framework\Setup\Declaration\Schema\Diff\Diff; +use Magento\Framework\Setup\Declaration\Schema\Dto\Schema; +use Magento\Framework\Setup\Declaration\Schema\Dto\SchemaFactory; use Magento\Framework\Setup\JsonPersistor; use Magento\Framework\Setup\Declaration\Schema\Declaration\ReaderComposite; use Symfony\Component\Console\Command\Command; @@ -50,22 +53,38 @@ class TablesWhitelistGenerateCommand extends Command */ private $primaryDbSchema; + /** + * @var SchemaFactory + */ + private $schemaFactory; + + /** + * @var SchemaBuilder + */ + private $schemaBuilder; + /** * @param ComponentRegistrar $componentRegistrar * @param ReaderComposite $readerComposite * @param JsonPersistor $jsonPersistor + * @param SchemaFactory $schemaFactory + * @param SchemaBuilder $schemaBuilder * @param string|null $name */ public function __construct( ComponentRegistrar $componentRegistrar, ReaderComposite $readerComposite, JsonPersistor $jsonPersistor, + SchemaFactory $schemaFactory, + SchemaBuilder $schemaBuilder, $name = null ) { parent::__construct($name); $this->componentRegistrar = $componentRegistrar; $this->readerComposite = $readerComposite; $this->jsonPersistor = $jsonPersistor; + $this->schemaFactory = $schemaFactory; + $this->schemaBuilder = $schemaBuilder; } /** @@ -98,6 +117,7 @@ protected function configure() * * @param string $moduleName * @return void + * @throws \Magento\Framework\Setup\Exception */ private function persistModule($moduleName) { @@ -113,15 +133,20 @@ private function persistModule($moduleName) $content = json_decode(file_get_contents($whiteListFileName), true); } - $newContent = $this->filterPrimaryTables($this->readerComposite->read($moduleName)); + $schema = $this->schemaFactory->create(); + $data = $this->filterPrimaryTables($this->readerComposite->read($moduleName)); + if (isset($data['table'])) { + $this->schemaBuilder->addTablesData($data['table']); + $schema = $this->schemaBuilder->build($schema); - //Do merge between what we have before, and what we have now and filter to only certain attributes. - $content = array_replace_recursive( - $content, - $this->filterAttributeNames($newContent) - ); - if (!empty($content)) { - $this->jsonPersistor->persist($content, $whiteListFileName); + //Do merge between what we have before, and what we have now and filter to only certain attributes. + $content = array_replace_recursive( + $content, + $this->getDeclaredContent($schema) + ); + if (!empty($content)) { + $this->jsonPersistor->persist($content, $whiteListFileName); + } } } @@ -149,27 +174,30 @@ protected function execute(InputInterface $input, OutputInterface $output) : int } /** - * Filter attribute names + * Convert Schema into a whitelist structure. * * As for whitelist we do not need any specific attributes like nullable or indexType, we need to choose only names. * - * @param array $content + * @param Schema $schema * @return array */ - private function filterAttributeNames(array $content) : array + private function getDeclaredContent(Schema $schema) : array { $names = []; - $types = ['column', 'index', 'constraint']; - - foreach ($content['table'] as $tableName => $tableContent) { - foreach ($types as $type) { - if (isset($tableContent[$type])) { - //Add elements to whitelist - foreach (array_keys($tableContent[$type]) as $elementName) { - //Depends on flag column will be whitelisted or not - $names[$tableName][$type][$elementName] = true; - } - } + foreach ($schema->getTables() as $tableName => $table) { + $columns = array_keys($table->getColumns()); + if ($columns) { + $names[$tableName]['column'] = array_fill_keys($columns, true); + } + + $indexes = array_keys($table->getIndexes()); + if ($indexes) { + $names[$tableName]['index'] = array_fill_keys($indexes, true); + } + + $constraints = array_keys($table->getConstraints()); + if ($constraints) { + $names[$tableName]['constraint'] = array_fill_keys($constraints, true); } } diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml index 1c4e7b6b6da97..ae6c98e4627d2 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml @@ -53,15 +53,15 @@ <column xsi:type="boolean" name="boolean"/> <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> <!--Constraints--> - <constraint xsi:type="unique" referenceId="TEST_TABLE_SMALLINT_BIGINT"> + <constraint xsi:type="unique" referenceId="TEST_TABLE_UNIQUE"> <column name="smallint"/> <column name="bigint"/> </constraint> - <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF" + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE" column="tinyint" table="test_table" referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> <!--Indexes--> - <index referenceId="TEST_TABLE_TINYINT_BIGINT" indexType="btree"> + <index referenceId="TEST_TABLE_INDEX" indexType="btree"> <column name="tinyint"/> <column name="bigint"/> </index> diff --git a/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php b/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php index 77f2d741fc6b5..ef745d9e6fa4a 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php @@ -65,6 +65,7 @@ public function setUp() * * @moduleName Magento_TestSetupDeclarationModule1 * @dataProvider contentsDataProvider + * @throws \Exception */ public function testExecute(array $expectedWhitelistContent) { @@ -119,6 +120,7 @@ public function contentsDataProvider(): array 'constraint' => [ 'tinyint_primary' => true, + 'PRIMARY' => true, ], ], 'auto_increment_test' => From c9a8c738b0da805042275036a7cabd44db181b5b Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Sat, 20 Oct 2018 00:33:55 -0500 Subject: [PATCH 403/812] MAGETWO-71660: "Recently Ordered" widget conatins no more 5 products if qty of products > 5 - fix static test failures --- .../Magento/Sales/CustomerData/LastOrderedItemsTest.php | 2 ++ .../_files/order_with_customer_and_multiple_order_items.php | 1 + .../Magento/Sales/_files/order_with_multiple_items.php | 1 + 3 files changed, 4 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php b/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php index d0c2144c951e9..7800d2363b364 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\CustomerData; use Magento\Framework\ObjectManagerInterface; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php index 06d3667f4d057..08c54844f2749 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_customer_and_multiple_order_items.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); include __DIR__ . '/order_with_multiple_items.php'; include __DIR__ . '/../../../Magento/Customer/_files/customer.php'; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php index 4fa84e4e28f01..ae0523d34fd2f 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_multiple_items.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); require 'order.php'; /** @var \Magento\Catalog\Model\Product $product */ From 19fa9e312cf53113931c7fdc3e779d0aa95ef707 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Sat, 20 Oct 2018 10:08:15 -0500 Subject: [PATCH 404/812] MAGETWO-95532: Unable to upload image from TinyMCE3 --- .../Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 04115ccdcc480..e0898065a9d67 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -17,6 +17,9 @@ <description value="Verify that admin is able to upload image to CMS Page with TinyMCE3 enabled"/> <severity value="MAJOR"/> <testCaseId value="MAGETWO-95725"/> + <skip> + <issueId value="MAGETWO-95799"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From 80669e3c52cd94ce60f5ee2e31eda78584bba97e Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Sat, 20 Oct 2018 18:31:29 +0300 Subject: [PATCH 405/812] graphQl-44: added ProductTextAttributeInput --- .../Resolver/Product/ProductTextAttribute.php | 6 ++-- .../ProductTextAttribute/FormatList.php | 13 +++++-- .../Product/ProductTextAttribute/Html.php | 2 +- .../CatalogGraphQl/etc/schema.graphqls | 34 ++++++++++++++----- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php index 7649464e2e1ca..2ff6faa0a74ee 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -39,7 +39,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function resolve( Field $field, @@ -55,8 +55,8 @@ public function resolve( /* @var $product Product */ $product = $value['model']; $fieldName = $field->getName(); - $formatIdentifier = $args['format'] ?? $this->defaultFormat; - $format = $this->formatList->create($formatIdentifier); + $formatIdentifier = $args['filter']['description']['format'] ?? $this->defaultFormat; + $format = $this->formatList->getFormatByIdentifier($formatIdentifier); $result = ['content' => $format->getContent($product, $fieldName)]; return $result; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php index 2e2f21d643092..39f2074ed7592 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php @@ -7,8 +7,13 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\ObjectManagerInterface; +/** + * Class FormatList + * @package Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute + */ class FormatList { /** @@ -37,10 +42,12 @@ public function __construct( * @param string $formatIdentifier * @return FormatInterface */ - public function create(string $formatIdentifier) : FormatInterface + public function getFormatByIdentifier(string $formatIdentifier) : FormatInterface { - $formatClassName = 'Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\\' . ucfirst($formatIdentifier); - $formatInstance = $this->objectManager->get($formatClassName); + if (!isset($this->formats[$formatIdentifier])) { + throw new GraphQlInputException(__('Format %1 does not exist.', [$formatIdentifier])); + } + $formatInstance = $this->objectManager->get($this->formats[$formatIdentifier]); return $formatInstance; } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php index 75c29a3f78fac..830fbf28e3373 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php @@ -44,4 +44,4 @@ public function getContent( ): string { return $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); } -} \ No newline at end of file +} diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 944cae6537bb0..a7d9ab5483d46 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") + description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -433,8 +433,8 @@ type CategoryProducts @doc(description: "The category products object returned i input ProductFilterInput @doc(description: "ProductFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") { name: FilterTypeInput @doc(description: "The product name. Customers use this name to identify the product.") sku: FilterTypeInput @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: FilterTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: FilterTypeInput @doc(description: "A short description of the product. Its use depends on the theme.") + description: ProductTextAttributeTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: ProductTextAttributeTypeInput @doc(description: "A short description of the product. Its use depends on the theme.") price: FilterTypeInput @doc(description: "The price of an item") special_price: FilterTypeInput @doc(description: "The discounted price of the product") special_from_date: FilterTypeInput @doc(description: "The beginning date that a product has a special price") @@ -557,9 +557,25 @@ type SortFields @doc(description: "SortFields contains a default value for sort options: [SortField] @doc(description: "Available sort fields") } -type ProductTextAttribute { - content ( - format: String @doc(description: "The format of content") -): String @doc(description: "The format of content") - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") +type ProductTextAttribute @doc(description: "Product text attribute.") { + content: String +} + +input ProductTextAttributeTypeInput @doc(description: "FilterTypeInput specifies which action will be performed in a query ") { + format: String @doc(description: "Format of the content") + eq: String @doc(description: "Equals") + finset: [String] @doc(description: "Find in set. The value can contain a set of comma-separated values") + from: String @doc(description: "From. Must be used with 'to'") + gt: String @doc(description: "Greater than") + gteq: String @doc(description: "Greater than or equal to") + in: [String] @doc(description: "In. The value can contain a set of comma-separated values") + like: String @doc(description: "Like. The specified value can contain % (percent signs) to allow matching of 0 or more characters") + lt: String @doc(description: "Less than") + lteq: String @doc(description: "Less than or equal to") + moreq: String @doc(description: "More than or equal to") + neq: String @doc(description: "Not equal to") + notnull: String @doc(description: "Not null") + null: String @doc(description: "Is null") + to: String@doc(description: "To. Must be used with 'from'") + nin: [String] @doc(description: "Not in. The value can contain a set of comma-separated values") } From ed6a2fba850caa5e2402663fee133d4f56545200 Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Sat, 20 Oct 2018 12:11:28 -0400 Subject: [PATCH 406/812] Prevent exception when option text converts to false The function would incorrectly through an exception when the option text was set to a string that would evaluate to false such as "0" Fixes #13083 --- .../Magento/Eav/Model/Entity/Attribute/OptionManagement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/OptionManagement.php b/app/code/Magento/Eav/Model/Entity/Attribute/OptionManagement.php index 4e4e146208a47..3c3bc083fdf8f 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/OptionManagement.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/OptionManagement.php @@ -141,7 +141,7 @@ public function getItems($entityType, $attributeCode) */ protected function validateOption($attribute, $optionId) { - if (!$attribute->getSource()->getOptionText($optionId)) { + if ($attribute->getSource()->getOptionText($optionId) === false) { throw new NoSuchEntityException( __( 'The "%1" attribute doesn\'t include an option with "%2" ID.', From 8bea285e9a51e5b759256c25d18b4c34fe7648ce Mon Sep 17 00:00:00 2001 From: Tomash Khamlai <tomash.khamlai@gmail.com> Date: Sat, 20 Oct 2018 22:52:03 +0300 Subject: [PATCH 407/812] Set fallback values for email and _website columns to avoid 'undefined index' error in CustomerComposite.php CLA will be signed --- .../CustomerImportExport/Model/Import/CustomerComposite.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CustomerImportExport/Model/Import/CustomerComposite.php b/app/code/Magento/CustomerImportExport/Model/Import/CustomerComposite.php index 956c9695623bb..2086f41d27fa6 100644 --- a/app/code/Magento/CustomerImportExport/Model/Import/CustomerComposite.php +++ b/app/code/Magento/CustomerImportExport/Model/Import/CustomerComposite.php @@ -299,8 +299,8 @@ public function validateData() $rows = []; foreach ($source as $row) { $rows[] = [ - Address::COLUMN_EMAIL => $row[Customer::COLUMN_EMAIL], - Address::COLUMN_WEBSITE => $row[Customer::COLUMN_WEBSITE], + Address::COLUMN_EMAIL => $row[Customer::COLUMN_EMAIL] ?? null, + Address::COLUMN_WEBSITE => $row[Customer::COLUMN_WEBSITE] ?? null ]; } $source->rewind(); From 76a7243995ce3d6ba205df8386da6c6d392b71dd Mon Sep 17 00:00:00 2001 From: Ronak Patel <ronak2ram@gmail.com> Date: Sun, 21 Oct 2018 12:45:04 +0530 Subject: [PATCH 408/812] Fixed - Total pages field returns null in category query --- .../CatalogGraphQl/Model/Resolver/Category/Products.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php index 557c7e08ff432..7a41f8fc94e74 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php @@ -92,7 +92,8 @@ public function resolve( 'items' => $searchResult->getProductsSearchResult(), 'page_info' => [ 'page_size' => $searchCriteria->getPageSize(), - 'current_page' => $currentPage + 'current_page' => $currentPage, + 'total_pages' => $maxPages ] ]; return $data; From 111bc284c94d56327ad8a5d3dc997a70fde84bae Mon Sep 17 00:00:00 2001 From: Nikita Titov <nekit94-08@mail.ru> Date: Sun, 21 Oct 2018 14:40:36 +0300 Subject: [PATCH 409/812] Updated links in README --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c292f1100f336..979e60a167748 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ Welcome to Magento 2 installation! We're glad you chose to install Magento 2, a cutting-edge, feature-rich eCommerce solution that gets results. ## Magento system requirements -[Magento system requirements](http://devdocs.magento.com/guides/v2.3/install-gde/system-requirements2.html). +[Magento system requirements](https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements2.html). ## Install Magento -* [Installation guide](http://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html). +* [Installation guide](https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html). <h2>Contributing to the Magento 2 code base</h2> Contributions can take the form of new components or features, changes to existing features, tests, documentation (such as developer guides, user guides, examples, or specifications), bug fixes, optimizations, or just good suggestions. @@ -21,10 +21,10 @@ To learn about issues, click [here][2]. To open an issue, click [here][3]. To suggest documentation improvements, click [here][4]. -[1]: <http://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html> -[2]: <http://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html#report> +[1]: <https://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html> +[2]: <https://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html#report> [3]: <https://github.com/magento/magento2/issues> -[4]: <http://devdocs.magento.com> +[4]: <https://devdocs.magento.com> <h3>Community Maintainers</h3> The members of this team have been recognized for their outstanding commitment to maintaining and improving Magento. Magento has granted them permission to accept, merge, and reject pull requests, as well as review issues, and thanks these Community Maintainers for their valuable contributions. @@ -53,9 +53,9 @@ Stay up-to-date on the latest security news and patches for Magento by signing u Each Magento source file included in this distribution is licensed under OSL 3.0 or the Magento Enterprise Edition (MEE) license. -http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) -Please see LICENSE.txt for the full text of the OSL 3.0 license or contact license@magentocommerce.com for a copy. +[Open Software License (OSL 3.0)](https://opensource.org/licenses/osl-3.0.php). +Please see [LICENSE.txt](https://github.com/magento/magento2/blob/2.3-develop/LICENSE.txt) for the full text of the OSL 3.0 license or contact license@magentocommerce.com for a copy. Subject to Licensee's payment of fees and compliance with the terms and conditions of the MEE License, the MEE License supersedes the OSL 3.0 license for each source file. -Please see LICENSE_EE.txt for the full text of the MEE License or visit http://magento.com/legal/terms/enterprise. +Please see LICENSE_EE.txt for the full text of the MEE License or visit https://magento.com/legal/terms/enterprise. From 1b6ce27459ece1d6ddd2f1b3ef69114f004aeb68 Mon Sep 17 00:00:00 2001 From: GwanYeong Kim <gy741.kim@gmail.com> Date: Sun, 21 Oct 2018 21:45:51 +0900 Subject: [PATCH 410/812] Fix Useless use of Cat --- dev/travis/before_script.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 1dccc310c7a20..dbd9d1cd4fec1 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -72,7 +72,7 @@ case $TEST_SUITE in --base-path="$TRAVIS_BUILD_DIR" \ --repo='https://github.com/magento/magento2.git' \ --branch="$TRAVIS_BRANCH" - cat "$changed_files_ce" | sed 's/^/ + including /' + sed 's/^/ + including /' "$changed_files_ce" cd ../../.. ;; From c34e734c061209a766ad83d686b42ffa41378b27 Mon Sep 17 00:00:00 2001 From: Manuele Menozzi <mmenozzi@webgriffe.com> Date: Sun, 21 Oct 2018 17:20:28 +0200 Subject: [PATCH 411/812] Prevent MAGE_DIRS overwrite in pub/index.php --- pub/index.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pub/index.php b/pub/index.php index 457b83c529488..90b4778265447 100644 --- a/pub/index.php +++ b/pub/index.php @@ -25,12 +25,15 @@ } $params = $_SERVER; -$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = [ - DirectoryList::PUB => [DirectoryList::URL_PATH => ''], - DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'], - DirectoryList::STATIC_VIEW => [DirectoryList::URL_PATH => 'static'], - DirectoryList::UPLOAD => [DirectoryList::URL_PATH => 'media/upload'], -]; +$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = array_replace_recursive( + $params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS], + [ + DirectoryList::PUB => [DirectoryList::URL_PATH => ''], + DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'], + DirectoryList::STATIC_VIEW => [DirectoryList::URL_PATH => 'static'], + DirectoryList::UPLOAD => [DirectoryList::URL_PATH => 'media/upload'], + ] +); $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params); /** @var \Magento\Framework\App\Http $app */ $app = $bootstrap->createApplication(\Magento\Framework\App\Http::class); From 19a2d2f2a2156b96733fadc88e16d07e871aadf7 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Sun, 21 Oct 2018 20:58:29 +0300 Subject: [PATCH 412/812] Sections less mixins: fix the issue with missing rules and incorrect default variables #18729 --- lib/web/css/source/lib/_sections.less | 15 +++++++++------ lib/web/css/source/lib/variables/_sections.less | 7 +++++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/web/css/source/lib/_sections.less b/lib/web/css/source/lib/_sections.less index 372008d061580..b73e317835955 100644 --- a/lib/web/css/source/lib/_sections.less +++ b/lib/web/css/source/lib/_sections.less @@ -49,16 +49,16 @@ @_tab-control-color: @tab-control__color, @_tab-control-text-decoration: @tab-control__text-decoration, - @_tab-control-color-visited: @tab-control__color, - @_tab-control-text-decoration-visited: @tab-control__text-decoration, + @_tab-control-color-visited: @tab-control__visited__color, + @_tab-control-text-decoration-visited: @tab-control__visited__text-decoration, @_tab-control-background-color-hover: @tab-control__hover__background-color, @_tab-control-color-hover: @tab-control__hover__color, - @_tab-control-text-decoration-hover: @tab-control__text-decoration, + @_tab-control-text-decoration-hover: @tab-control__hover__text-decoration, @_tab-control-background-color-active: @tab-control__active__background-color, @_tab-control-color-active: @tab-control__active__color, - @_tab-control-text-decoration-active: @tab-control__text-decoration, + @_tab-control-text-decoration-active: @tab-control__active__text-decoration, @_tab-control-height: @tab-control__height, @_tab-control-margin-right: @tab-control__margin-right, @@ -121,6 +121,7 @@ &.active > .switch:hover { .lib-css(background, @_tab-control-background-color-active); .lib-css(color, @_tab-control-color-active); + .lib-css(text-decoration, @_tab-control-text-decoration-active); } &.active > .switch, @@ -200,8 +201,8 @@ @_accordion-control-color: @accordion-control__color, @_accordion-control-text-decoration: @accordion-control__text-decoration, - @_accordion-control-color-visited: @accordion-control__color, - @_accordion-control-text-decoration-visited: @accordion-control__text-decoration, + @_accordion-control-color-visited: @accordion-control__visited__color, + @_accordion-control-text-decoration-visited: @accordion-control__visited__text-decoration, @_accordion-control-background-color-hover: @accordion-control__hover__background-color, @_accordion-control-color-hover: @accordion-control__hover__color, @@ -275,6 +276,8 @@ &.active > .switch:focus, &.active > .switch:hover { .lib-css(background, @_accordion-control-background-color-active); + .lib-css(color, @_accordion-control-color-active); + .lib-css(text-decoration, @_accordion-control-text-decoration-active); .lib-css(padding-bottom, @_accordion-control-padding-bottom); } } diff --git a/lib/web/css/source/lib/variables/_sections.less b/lib/web/css/source/lib/variables/_sections.less index 7d961077e6f59..0868ce73c49ef 100644 --- a/lib/web/css/source/lib/variables/_sections.less +++ b/lib/web/css/source/lib/variables/_sections.less @@ -40,6 +40,9 @@ @tab-control__active__color: @text__color; @tab-control__active__text-decoration: @tab-control__text-decoration; +@tab-control__visited__color: @accordion-control__color; +@tab-control__visited__text-decoration: @accordion-control__text-decoration; + @tab-content__background-color: @tab-control__active__background-color; @tab-content__border-top-status: false; @tab-content__border: @tab-control__border-width solid @tab-control__border-color; @@ -72,8 +75,8 @@ @accordion-control__padding-bottom: @tab-control__padding-bottom; @accordion-control__padding-left: @accordion-control__padding-right; -@accordion-control__visited__color: @accordion-control__color; -@accordion-control__visited__text-decoration: @accordion-control__text-decoration; +@accordion-control__visited__color: @tab-control__visited__color; +@accordion-control__visited__text-decoration: @tab-control__visited__text-decoration; @accordion-control__hover__background-color: @tab-control__hover__background-color; @accordion-control__hover__color: @tab-control__hover__color; From 310afd896e0c3cc82d81e50f92dff928c231f2bc Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Sun, 21 Oct 2018 21:36:13 +0300 Subject: [PATCH 413/812] Fix a typo in variable name #18730 --- lib/web/css/source/lib/variables/_sections.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/web/css/source/lib/variables/_sections.less b/lib/web/css/source/lib/variables/_sections.less index 0868ce73c49ef..05226d8aa3a3c 100644 --- a/lib/web/css/source/lib/variables/_sections.less +++ b/lib/web/css/source/lib/variables/_sections.less @@ -40,8 +40,8 @@ @tab-control__active__color: @text__color; @tab-control__active__text-decoration: @tab-control__text-decoration; -@tab-control__visited__color: @accordion-control__color; -@tab-control__visited__text-decoration: @accordion-control__text-decoration; +@tab-control__visited__color: @tab-control__color; +@tab-control__visited__text-decoration: @tab-control__text-decoration; @tab-content__background-color: @tab-control__active__background-color; @tab-content__border-top-status: false; From a4b5cc1106f69325ab21774c0b5d86653101a2a0 Mon Sep 17 00:00:00 2001 From: Pratik Oza <pratik.oza@krishtechnolabs.com> Date: Mon, 22 Oct 2018 01:19:55 +0530 Subject: [PATCH 414/812] Correct a typo in the reference to ISO language codes --- app/code/Magento/Deploy/Console/DeployStaticOptions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Deploy/Console/DeployStaticOptions.php b/app/code/Magento/Deploy/Console/DeployStaticOptions.php index 9a73dd5d65fc7..89cb3e4b30345 100644 --- a/app/code/Magento/Deploy/Console/DeployStaticOptions.php +++ b/app/code/Magento/Deploy/Console/DeployStaticOptions.php @@ -240,7 +240,7 @@ private function getBasicOptions() new InputArgument( self::LANGUAGES_ARGUMENT, InputArgument::IS_ARRAY, - 'Space-separated list of ISO-636 language codes for which to output static view files.' + 'Space-separated list of ISO-639 language codes for which to output static view files.' ), ]; } From 4662ca91833b95662b8f7098718026153c290d05 Mon Sep 17 00:00:00 2001 From: vprohorov <vitaliy_prokharau@epam.com> Date: Mon, 22 Oct 2018 14:25:06 +0300 Subject: [PATCH 415/812] MAGETWO-91537: Search synonyms results missing for words including hyphen and numbers - Fixing test --- .../Magento/Catalog/Test/Repository/CatalogProductSimple.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 721b0ff570079..e90ca6bf7868a 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 @@ -41,7 +41,7 @@ <field name="attribute_set_id" xsi:type="array"> <item name="dataset" xsi:type="string">default</item> </field> - <field name="name" xsi:type="string">Product \'!@#$%^&*()+:;\\|}{][?=-~` %isolation%</field> + <field name="name" xsi:type="string">Product \'!@#$%^&*()+:;\\|}{][?=~` %isolation%</field> <field name="sku" xsi:type="string">sku_simple_product_%isolation%</field> <field name="is_virtual" xsi:type="string">No</field> <field name="product_has_weight" xsi:type="string">This item has weight</field> From 65dac5da0815119255b15e9dcec1fe4f955571a6 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Mon, 22 Oct 2018 14:56:47 +0300 Subject: [PATCH 416/812] MAGETWO-95654: Constraint removal is not treated as destructive operation - Added foreign key for 'magento_bulk' table; --- app/code/Magento/AsynchronousOperations/etc/db_schema.xml | 2 ++ .../AsynchronousOperations/etc/db_schema_whitelist.json | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml index 342326e6666f1..95bd9bdcab283 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml @@ -27,6 +27,8 @@ <constraint xsi:type="unique" name="MAGENTO_BULK_UUID"> <column name="uuid"/> </constraint> + <constraint xsi:type="foreign" name="MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID" table="magento_bulk" + column="user_id" referenceTable="admin_user" referenceColumn="user_id" onDelete="CASCADE"/> <index name="MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID" indexType="btree"> <column name="user_id"/> </index> diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json b/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json index 423b7553ced2a..9b6c0709e1916 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema_whitelist.json @@ -15,7 +15,8 @@ }, "constraint": { "PRIMARY": true, - "MAGENTO_BULK_UUID": true + "MAGENTO_BULK_UUID": true, + "MAGENTO_BULK_USER_ID_ADMIN_USER_USER_ID": true } }, "magento_operation": { From fe600f2d231ef8146837cc6172b8f92e96234ffd Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 22 Oct 2018 15:34:12 +0200 Subject: [PATCH 417/812] Minor code style fixes --- .../GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php b/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php index f82bc01c485e9..7a3000f7c0743 100644 --- a/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php +++ b/app/code/Magento/GiftMessage/Test/Unit/Observer/SalesEventQuoteMergeTest.php @@ -10,7 +10,7 @@ use Magento\GiftMessage\Observer\SalesEventQuoteMerge; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use \Magento\Framework\Event\Observer; +use Magento\Framework\Event\Observer; use Magento\Quote\Model\Quote; /** From 93c6073eca8f6611ad3702b17861dd4aee7a9364 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 22 Oct 2018 15:55:02 +0200 Subject: [PATCH 418/812] Attempt to determine why GraphQl test modules are not present in the env --- dev/travis/before_script.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index c27e65d3897c7..52fd44c2826cc 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -152,6 +152,9 @@ case $TEST_SUITE in --admin-use-security-key=0 \ --admin-password="123123q" + php bin/magento module:status # DEBUG + php bin/magento setup:upgrade # DEBUG + echo "Enabling production mode" php bin/magento deploy:mode:set production From f9a7b81238135a51f964ef861e26c9ec6aa557e9 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 22 Oct 2018 16:17:31 +0200 Subject: [PATCH 419/812] Temporarily disable all other tests except api-fucntional --- .travis.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index f5a25bc63543d..930172a9ea6e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,14 +25,14 @@ env: - NODE_JS_VERSION=8 - MAGENTO_HOST_NAME="magento2.travis" matrix: - - TEST_SUITE=unit - - TEST_SUITE=static - - TEST_SUITE=js GRUNT_COMMAND=spec - - TEST_SUITE=js GRUNT_COMMAND=static - - TEST_SUITE=integration INTEGRATION_INDEX=1 - - TEST_SUITE=integration INTEGRATION_INDEX=2 - - TEST_SUITE=integration INTEGRATION_INDEX=3 - - TEST_SUITE=functional +# - TEST_SUITE=unit +# - TEST_SUITE=static +# - TEST_SUITE=js GRUNT_COMMAND=spec +# - TEST_SUITE=js GRUNT_COMMAND=static +# - TEST_SUITE=integration INTEGRATION_INDEX=1 +# - TEST_SUITE=integration INTEGRATION_INDEX=2 +# - TEST_SUITE=integration INTEGRATION_INDEX=3 +# - TEST_SUITE=functional - TEST_SUITE=api-functional matrix: exclude: From c954022c288af8703c888ceb0dcb492f52cac97f Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Mon, 22 Oct 2018 09:47:33 -0500 Subject: [PATCH 420/812] MAGETWO-95799: [Flaky test]Stabilize AdminAddImageToCMSPageTinyMCE3Test - stabilize test --- .../Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 9 ++++++--- .../Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 04115ccdcc480..9d3b498dc6ce6 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -20,14 +20,16 @@ </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> + <magentoCLI command="config:set cms/wysiwyg/enabled enabled" stepKey="enableWYSIWYG"/> <!-- Choose TinyMCE3 as the default WYSIWYG editor--> - <actionGroup ref="SwitchToTinyMCE3" stepKey="switchToTinyMCE3"/> + <!--<actionGroup ref="SwitchToTinyMCE3" stepKey="switchToTinyMCE3"/>--> + <magentoCLI command="config:set cms/wysiwyg/editor Magento_Tinymce3/tinymce3Adapter" stepKey="enableTinyMCE3"/> </before> <after> <!-- Switch WYSIWYG editor to TinyMCE4--> <comment userInput="Reset editor as TinyMCE4" stepKey="chooseTinyMCE4AsEditor"/> - <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4"/> + <!--<actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4"/>--> + <magentoCLI command="config:set cms/wysiwyg/editor mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter" stepKey="enableTinyMCE4"/> <actionGroup ref="logout" stepKey="logout"/> </after> <amOnPage url="{{CmsNewPagePage.url}}" stepKey="navigateToPage2"/> @@ -36,6 +38,7 @@ <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab2" /> <waitForElementVisible selector="{{TinyMCESection.TinyMCE3}}" stepKey="waitForTinyMCE3"/> <seeElement selector="{{TinyMCESection.TinyMCE3}}" stepKey="seeTinyMCE3" /> + <wait time="3" stepKey="waiting"/> <comment userInput="Click Insert image button" stepKey="clickImageButton"/> <click selector="{{TinyMCESection.InsertImageBtnTinyMCE3}}" stepKey="clickInsertImage" /> <waitForPageLoad stepKey="waitForiFrameToLoad" /> diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml index 2d784842ea46a..307999ce48e4d 100644 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigWYSIWYGActionGroup.xml @@ -28,6 +28,7 @@ <selectOption selector="{{ContentManagementSection.Switcher}}" userInput="TinyMCE 3" stepKey="switchToVersion3" /> <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="collapseWYSIWYGOptions" /> <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig" /> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeConfigurationSuccessMessage"/> </actionGroup> <actionGroup name="DisabledWYSIWYG"> <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToConfigurationPage" /> From bca0e5e9e9117b28d69ae24161a690644ab4dac2 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Sun, 21 Oct 2018 22:38:05 -0500 Subject: [PATCH 421/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../TablesWhitelistGenerateCommand.php | 169 +----------- .../Declaration/Schema/WhitelistGenerator.php | 258 ++++++++++++++++++ .../Schema/Declaration/SchemaBuilder.php | 72 +---- .../TableElement/ElementNameResolver.php | 190 +++++++++++++ .../Schema/Dto/Factories/Foreign.php | 34 +-- .../Schema/Dto/Factories/Index.php | 40 ++- .../Schema/Dto/Factories/Unique.php | 32 +-- .../Setup/Declaration/Schema/Dto/Table.php | 16 +- .../Setup/Declaration/Schema/etc/index.xsd | 2 +- .../Setup/Declaration/Schema/etc/schema.xsd | 31 ++- 10 files changed, 569 insertions(+), 275 deletions(-) create mode 100644 app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php create mode 100644 lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php diff --git a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php index 1832cfce7f158..9e1f9252c84b6 100644 --- a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php +++ b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php @@ -7,15 +7,9 @@ namespace Magento\Developer\Console\Command; -use Magento\Framework\Component\ComponentRegistrar; +use Magento\Developer\Model\Setup\Declaration\Schema\WhitelistGenerator; use Magento\Framework\Config\FileResolverByModule; -use Magento\Framework\Module\Dir; -use Magento\Framework\Setup\Declaration\Schema\Declaration\SchemaBuilder; -use Magento\Framework\Setup\Declaration\Schema\Diff\Diff; -use Magento\Framework\Setup\Declaration\Schema\Dto\Schema; -use Magento\Framework\Setup\Declaration\Schema\Dto\SchemaFactory; -use Magento\Framework\Setup\JsonPersistor; -use Magento\Framework\Setup\Declaration\Schema\Declaration\ReaderComposite; +use Magento\Framework\Exception\ConfigurationMismatchException; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -34,57 +28,20 @@ class TablesWhitelistGenerateCommand extends Command const MODULE_NAME_KEY = 'module-name'; /** - * @var ComponentRegistrar + * @var WhitelistGenerator */ - private $componentRegistrar; + private $whitelistGenerator; /** - * @var ReaderComposite - */ - private $readerComposite; - - /** - * @var JsonPersistor - */ - private $jsonPersistor; - - /** - * @var array - */ - private $primaryDbSchema; - - /** - * @var SchemaFactory - */ - private $schemaFactory; - - /** - * @var SchemaBuilder - */ - private $schemaBuilder; - - /** - * @param ComponentRegistrar $componentRegistrar - * @param ReaderComposite $readerComposite - * @param JsonPersistor $jsonPersistor - * @param SchemaFactory $schemaFactory - * @param SchemaBuilder $schemaBuilder + * @param WhitelistGenerator $whitelistGenerator * @param string|null $name */ public function __construct( - ComponentRegistrar $componentRegistrar, - ReaderComposite $readerComposite, - JsonPersistor $jsonPersistor, - SchemaFactory $schemaFactory, - SchemaBuilder $schemaBuilder, + WhitelistGenerator $whitelistGenerator, $name = null ) { + $this->whitelistGenerator = $whitelistGenerator; parent::__construct($name); - $this->componentRegistrar = $componentRegistrar; - $this->readerComposite = $readerComposite; - $this->jsonPersistor = $jsonPersistor; - $this->schemaFactory = $schemaFactory; - $this->schemaBuilder = $schemaBuilder; } /** @@ -112,44 +69,6 @@ protected function configure() parent::configure(); } - /** - * Update whitelist tables for all modules that are enabled on the moment. - * - * @param string $moduleName - * @return void - * @throws \Magento\Framework\Setup\Exception - */ - private function persistModule($moduleName) - { - $content = []; - $modulePath = $this->componentRegistrar->getPath('module', $moduleName); - $whiteListFileName = $modulePath - . DIRECTORY_SEPARATOR - . Dir::MODULE_ETC_DIR - . DIRECTORY_SEPARATOR - . Diff::GENERATED_WHITELIST_FILE_NAME; - //We need to load whitelist file and update it with new revision of code. - if (file_exists($whiteListFileName)) { - $content = json_decode(file_get_contents($whiteListFileName), true); - } - - $schema = $this->schemaFactory->create(); - $data = $this->filterPrimaryTables($this->readerComposite->read($moduleName)); - if (isset($data['table'])) { - $this->schemaBuilder->addTablesData($data['table']); - $schema = $this->schemaBuilder->build($schema); - - //Do merge between what we have before, and what we have now and filter to only certain attributes. - $content = array_replace_recursive( - $content, - $this->getDeclaredContent($schema) - ); - if (!empty($content)) { - $this->jsonPersistor->persist($content, $whiteListFileName); - } - } - } - /** * @inheritdoc */ @@ -158,80 +77,14 @@ protected function execute(InputInterface $input, OutputInterface $output) : int $moduleName = $input->getOption(self::MODULE_NAME_KEY); try { - if ($moduleName === FileResolverByModule::ALL_MODULES) { - foreach (array_keys($this->componentRegistrar->getPaths('module')) as $moduleName) { - $this->persistModule($moduleName); - } - } else { - $this->persistModule($moduleName); - } + $this->whitelistGenerator->generate($moduleName); + } catch (ConfigurationMismatchException $e) { + $output->writeln("<info>". $e . "</info>"); + return \Magento\Framework\Console\Cli::RETURN_FAILURE; } catch (\Exception $e) { return \Magento\Framework\Console\Cli::RETURN_FAILURE; } - //If script comes here, that we sucessfully write whitelist configuration return \Magento\Framework\Console\Cli::RETURN_SUCCESS; } - - /** - * Convert Schema into a whitelist structure. - * - * As for whitelist we do not need any specific attributes like nullable or indexType, we need to choose only names. - * - * @param Schema $schema - * @return array - */ - private function getDeclaredContent(Schema $schema) : array - { - $names = []; - foreach ($schema->getTables() as $tableName => $table) { - $columns = array_keys($table->getColumns()); - if ($columns) { - $names[$tableName]['column'] = array_fill_keys($columns, true); - } - - $indexes = array_keys($table->getIndexes()); - if ($indexes) { - $names[$tableName]['index'] = array_fill_keys($indexes, true); - } - - $constraints = array_keys($table->getConstraints()); - if ($constraints) { - $names[$tableName]['constraint'] = array_fill_keys($constraints, true); - } - } - - return $names; - } - - /** - * Load db_schema content from the primary scope app/etc/db_schema.xml. - * - * @return array - */ - private function getPrimaryDbSchema() - { - if (!$this->primaryDbSchema) { - $this->primaryDbSchema = $this->readerComposite->read('primary'); - } - return $this->primaryDbSchema; - } - - /** - * Filter tables from module db_schema.xml as they should not contain the primary system tables. - * - * @param array $moduleDbSchema - * @return array - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - private function filterPrimaryTables(array $moduleDbSchema) - { - $primaryDbSchema = $this->getPrimaryDbSchema(); - if (isset($moduleDbSchema['table']) && isset($primaryDbSchema['table'])) { - foreach ($primaryDbSchema['table'] as $tableNameKey => $tableContents) { - unset($moduleDbSchema['table'][$tableNameKey]); - } - } - return $moduleDbSchema; - } } diff --git a/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php b/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php new file mode 100644 index 0000000000000..af20619934d68 --- /dev/null +++ b/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php @@ -0,0 +1,258 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Developer\Model\Setup\Declaration\Schema; + +use Magento\Framework\App\DeploymentConfig; +use Magento\Framework\Component\ComponentRegistrar; +use Magento\Framework\Config\ConfigOptionsListConstants; +use Magento\Framework\Config\FileResolverByModule; +use Magento\Framework\Exception\ConfigurationMismatchException; +use Magento\Framework\Module\Dir; +use Magento\Framework\Setup\Declaration\Schema\Declaration\ReaderComposite; +use Magento\Framework\Setup\Declaration\Schema\Declaration\TableElement\ElementNameResolver; +use Magento\Framework\Setup\Declaration\Schema\Diff\Diff; +use Magento\Framework\Setup\Declaration\Schema\Dto\Schema; +use Magento\Framework\Setup\Declaration\Schema\SchemaConfig; +use Magento\Framework\Setup\JsonPersistor; + +/** + * Generate whitelist declaration declarative schema. + */ +class WhitelistGenerator +{ + /** + * @var SchemaConfig + */ + private $schemaConfig; + + /** + * @var ComponentRegistrar + */ + private $componentRegistrar; + + /** + * @var JsonPersistor + */ + private $jsonPersistor; + + /** + * @var ReaderComposite + */ + private $readerComposite; + + /** + * @var array + */ + private $primaryDbSchema; + + /** + * @var ElementNameResolver + */ + private $elementNameResolver; + + /** + * @var DeploymentConfig + */ + private $deploymentConfig; + + /** + * @param ComponentRegistrar $componentRegistrar + * @param JsonPersistor $jsonPersistor + * @param SchemaConfig $schemaConfig + * @param ReaderComposite $readerComposite + * @param ElementNameResolver $elementNameResolver + * @param DeploymentConfig $deploymentConfig + */ + public function __construct( + ComponentRegistrar $componentRegistrar, + JsonPersistor $jsonPersistor, + SchemaConfig $schemaConfig, + ReaderComposite $readerComposite, + ElementNameResolver $elementNameResolver, + DeploymentConfig $deploymentConfig + ) { + $this->componentRegistrar = $componentRegistrar; + $this->jsonPersistor = $jsonPersistor; + $this->schemaConfig = $schemaConfig; + $this->readerComposite = $readerComposite; + $this->elementNameResolver = $elementNameResolver; + $this->deploymentConfig = $deploymentConfig; + } + + /** + * Generate whitelist declaration. + * + * @param string $moduleName + * @throws ConfigurationMismatchException + */ + public function generate(string $moduleName) + { + $this->checkMagentoInstallation(); + $schema = $this->schemaConfig->getDeclarationConfig(); + if ($moduleName === FileResolverByModule::ALL_MODULES) { + foreach (array_keys($this->componentRegistrar->getPaths('module')) as $moduleName) { + $this->persistModule($schema, $moduleName); + } + } else { + $this->persistModule($schema, $moduleName); + } + } + + /** + * Check the configuration of the installed instance. + * + * @throws ConfigurationMismatchException + */ + private function checkMagentoInstallation() + { + $tablePrefixLength = $this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_DB_PREFIX); + if ($tablePrefixLength) { + throw new ConfigurationMismatchException( + __('Magento was installed with a table prefix. Please re-install without prefix.') + ); + } + } + + /** + * Update whitelist tables for all modules that are enabled on the moment. + * + * @param Schema $schema + * @param string $moduleName + * @return void + */ + private function persistModule(Schema $schema, string $moduleName) + { + $content = []; + $modulePath = $this->componentRegistrar->getPath('module', $moduleName); + $whiteListFileName = $modulePath + . DIRECTORY_SEPARATOR + . Dir::MODULE_ETC_DIR + . DIRECTORY_SEPARATOR + . Diff::GENERATED_WHITELIST_FILE_NAME; + + //We need to load whitelist file and update it with new revision of code. + if (file_exists($whiteListFileName)) { + $content = json_decode(file_get_contents($whiteListFileName), true); + } + + $data = $this->filterPrimaryTables($this->readerComposite->read($moduleName)); + if (!empty($data['table'])) { + foreach ($data['table'] as $tableName => $tabledata) { + //Do merge between what we have before, and what we have now and filter to only certain attributes. + $content = array_replace_recursive( + $content, + [$tableName => $this->getElementsWithFixedName($tabledata)], + [$tableName => $this->getElementsWithAutogeneratedName( + $schema, + $tableName, + $tabledata + )] + ); + } + if (!empty($content)) { + $this->jsonPersistor->persist($content, $whiteListFileName); + } + } + } + + /** + * Provides immutable names of the table elements. + * + * @param array $tableData + * @return array + */ + private function getElementsWithFixedName(array $tableData): array + { + $declaredStructure = []; + if (!empty($tableData['column'])) { + $declaredColumns = array_keys($tableData['column']); + $declaredStructure['column'] = array_fill_keys($declaredColumns, true); + } + return $declaredStructure; + } + + /** + * Provides autogenerated names of the table elements. + * + * @param Schema $schema + * @param string $tableName + * @param array $tableData + * @return array + */ + private function getElementsWithAutogeneratedName(Schema $schema, string $tableName, array $tableData) : array + { + $declaredStructure = []; + $table = $schema->getTableByName($tableName); + + $elementType = 'index'; + if (!empty($tableData[$elementType])) { + foreach ($tableData[$elementType] as $tableElementData) { + $indexName = $this->elementNameResolver->getFullIndexName( + $table, + $tableElementData['column'], + $tableElementData['indexType'] ?? null + ); + $declaredStructure[$elementType][$indexName] = true; + } + } + + $elementType = 'constraint'; + if (!empty($tableData[$elementType])) { + foreach ($tableData[$elementType] as $tableElementData) { + if ($tableElementData['type'] === 'foreign') { + $referenceTable = $schema->getTableByName($tableElementData['referenceTable']); + $constraintName = $this->elementNameResolver->getFullFKName( + $table, + $table->getColumnByName($tableElementData['column']), + $referenceTable, + $referenceTable->getColumnByName($tableElementData['referenceColumn']) + ); + } else { + $constraintName = $this->elementNameResolver->getFullIndexName( + $table, + $tableElementData['column'], + $tableElementData['type'] + ); + } + $declaredStructure[$elementType][$constraintName] = true; + } + } + + return $declaredStructure; + } + + /** + * Load db_schema content from the primary scope app/etc/db_schema.xml. + * + * @return array + */ + private function getPrimaryDbSchema(): array + { + if (!$this->primaryDbSchema) { + $this->primaryDbSchema = $this->readerComposite->read('primary'); + } + return $this->primaryDbSchema; + } + + /** + * Filter tables from module database schema as they should not contain the primary system tables. + * + * @param array $moduleDbSchema + * @return array + */ + private function filterPrimaryTables(array $moduleDbSchema): array + { + $primaryDbSchema = $this->getPrimaryDbSchema(); + if (isset($moduleDbSchema['table']) && isset($primaryDbSchema['table'])) { + foreach (array_keys($primaryDbSchema['table']) as $tableNameKey) { + unset($moduleDbSchema['table'][$tableNameKey]); + } + } + return $moduleDbSchema; + } +} \ No newline at end of file diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php index 735b8273019f7..34a99f26a4ef1 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php @@ -7,9 +7,8 @@ namespace Magento\Framework\Setup\Declaration\Schema\Declaration; -use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\Phrase; -use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; +use Magento\Framework\Setup\Declaration\Schema\Declaration\TableElement\ElementNameResolver; use Magento\Framework\Stdlib\BooleanUtils; use Magento\Framework\Setup\Exception; use Magento\Framework\Setup\Declaration\Schema\Dto\Column; @@ -70,9 +69,9 @@ class SchemaBuilder private $resourceConnection; /** - * @var TableNameResolver + * @var ElementNameResolver */ - private $tableNameResolver; + private $elementNameResolver; /** * SchemaBuilder constructor. @@ -82,8 +81,7 @@ class SchemaBuilder * @param Sharding $sharding * @param ValidationComposite $validationComposite * @param \Magento\Framework\App\ResourceConnection $resourceConnection - * @param TableNameResolver $tableNameResolver - * @internal param array $tablesData + * @param ElementNameResolver $elementNameResolver */ public function __construct( ElementFactory $elementFactory, @@ -91,14 +89,14 @@ public function __construct( Sharding $sharding, ValidationComposite $validationComposite, \Magento\Framework\App\ResourceConnection $resourceConnection, - TableNameResolver $tableNameResolver + ElementNameResolver $elementNameResolver ) { $this->sharding = $sharding; $this->elementFactory = $elementFactory; $this->booleanUtils = $booleanUtils; $this->validationComposite = $validationComposite; $this->resourceConnection = $resourceConnection; - $this->tableNameResolver = $tableNameResolver; + $this->elementNameResolver = $elementNameResolver; } /** @@ -291,33 +289,6 @@ private function convertColumnNamesToObjects(array $columnNames, Table $table): return $columns; } - /** - * Provides the full index name based on the prefix value. - * - * @param Table $table - * @param array $columns - * @param string $type - * @return string - */ - private function getFullIndexName( - Table $table, - array $columns, - string $type = AdapterInterface::INDEX_TYPE_INDEX - ): string { - if (AdapterInterface::INDEX_TYPE_PRIMARY === $type) { - return strtoupper(AdapterInterface::INDEX_TYPE_PRIMARY); - } - - $tableName = $this->tableNameResolver->getNameOfOriginTable($table->getName()); - - return $this->resourceConnection - ->getIdxName( - $tableName, - $columns, - $type - ); - } - /** * Convert and instantiate index objects. * @@ -339,19 +310,10 @@ private function processIndexes(array $tableData, string $resource, Table $table continue; } - /** - * Temporary solution. - * @see MAGETWO-91365 - */ - $indexType = AdapterInterface::INDEX_TYPE_INDEX; - if (isset($indexData['indexType']) && $indexData['indexType'] === AdapterInterface::INDEX_TYPE_FULLTEXT) { - $indexType = $indexData['indexType']; - } - - $indexData['name'] = $this->getFullIndexName( + $indexData['name'] = $this->elementNameResolver->getFullIndexName( $table, $indexData['column'], - $indexType + $indexData['indexType'] ?? null ); $indexData = $this->processGenericData($indexData, $resource, $table); $indexData['columns'] = $this->convertColumnNamesToObjects($indexData['column'], $table); @@ -411,20 +373,16 @@ private function processConstraints(array $tableData, string $resource, Schema $ $constraintData['referenceColumn'], $constraintData['referenceTable'] ); - /** - * Calculation of the full name of Foreign Key based on the prefix value. - */ - $constraintData['name'] = $this->resourceConnection - ->getFkName( - $this->tableNameResolver->getNameOfOriginTable($table->getName()), - $constraintData['column']->getName(), - $constraintData['referenceTable']->getName(), - $constraintData['referenceColumn']->getName() - ); + $constraintData['name'] = $this->elementNameResolver->getFullFKName( + $table, + $constraintData['column'], + $constraintData['referenceTable'], + $constraintData['referenceColumn'] + ); $constraint = $this->elementFactory->create($constraintData['type'], $constraintData); $constraints[$constraint->getName()] = $constraint; } else { - $constraintData['name'] = $this->getFullIndexName( + $constraintData['name'] = $this->elementNameResolver->getFullIndexName( $table, $constraintData['column'], $constraintData['type'] diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php new file mode 100644 index 0000000000000..a3e66b9cf39c5 --- /dev/null +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php @@ -0,0 +1,190 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Setup\Declaration\Schema\Declaration\TableElement; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\Setup\Declaration\Schema\Dto\Column; +use Magento\Framework\Setup\Declaration\Schema\Dto\Table; +use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; + +/** + * Provides names of table elements with autogenerated names. + */ +class ElementNameResolver +{ + /** + * @var TableNameResolver + */ + private $tableNameResolver; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @param TableNameResolver $tableNameResolver + * @param ResourceConnection $resourceConnection + */ + public function __construct(TableNameResolver $tableNameResolver, ResourceConnection $resourceConnection) + { + $this->tableNameResolver = $tableNameResolver; + $this->resourceConnection = $resourceConnection; + } + + /** + * Provides the full index name based on the prefix value. + * + * @param Table $table + * @param string[] $columns + * @param string $type + * @return string + */ + public function getFullIndexName( + Table $table, + array $columns, + ?string $type = AdapterInterface::INDEX_TYPE_INDEX + ): string { + if (AdapterInterface::INDEX_TYPE_PRIMARY === $type) { + return strtoupper(AdapterInterface::INDEX_TYPE_PRIMARY); + } + + /** + * Temporary solution. + * @see MAGETWO-91365 + */ + if ($type + && !array_search( + $type, + [AdapterInterface::INDEX_TYPE_FULLTEXT, AdapterInterface::INDEX_TYPE_UNIQUE] + ) + ) { + $type = AdapterInterface::INDEX_TYPE_INDEX; + } + + $tableName = $this->tableNameResolver->getNameOfOriginTable($table->getName()); + + return $this->resourceConnection + ->getIdxName( + $tableName, + $columns, + $type + ); + } + + /** + * Provides the index name without prefix value. + * + * @param string $name + * @param Table $table + * @param string[] $columns + * @param string $type + * @return string + */ + public function getIndexNameWithoutPrefix( + string $name, + Table $table, + array $columns, + ?string $type = AdapterInterface::INDEX_TYPE_INDEX + ): string { + if (AdapterInterface::INDEX_TYPE_PRIMARY === $type) { + return strtoupper(AdapterInterface::INDEX_TYPE_PRIMARY); + } + + $nameWithoutPrefix = $name; + + if ($this->resourceConnection->getTablePrefix()) { + /** + * Temporary solution. + * @see MAGETWO-91365 + */ + if ($type + && !array_search( + $type, + [AdapterInterface::INDEX_TYPE_FULLTEXT, AdapterInterface::INDEX_TYPE_UNIQUE] + ) + ) { + $type = AdapterInterface::INDEX_TYPE_INDEX; + } + + $nameWithoutPrefix = $this->resourceConnection + ->getConnection($table->getResource()) + ->getIndexName( + $this->tableNameResolver->getNameOfOriginTable( + $table->getNameWithoutPrefix() + ), + $columns, + $type + ); + } + + return $nameWithoutPrefix; + } + + /** + * Provides the full foreign key name based on the prefix value. + * + * @param Table $table + * @param Column $column + * @param Table $referenceTable + * @param Column $referenceColumn + * @return string + */ + public function getFullFKName( + Table $table, + Column $column, + Table $referenceTable, + Column $referenceColumn + ): string { + $fkName = $this->resourceConnection + ->getFkName( + $this->tableNameResolver->getNameOfOriginTable($table->getName()), + $column->getName(), + $referenceTable->getName(), + $referenceColumn->getName() + ); + + return $fkName; + } + + /** + * Provides the foreign key name without prefix value. + * + * @param string $name + * @param Table $table + * @param Column $column + * @param Table $referenceTable + * @param Column $referenceColumn + * @return string + */ + public function getFKNameWithoutPrefix( + string $name, + Table $table, + Column $column, + Table $referenceTable, + Column $referenceColumn + ): string { + $nameWithoutPrefix = $name; + + if ($this->resourceConnection->getTablePrefix()) { + $nameWithoutPrefix = $this->resourceConnection + ->getConnection($table->getResource()) + ->getForeignKeyName( + $this->tableNameResolver->getNameOfOriginTable( + $table->getNameWithoutPrefix() + ), + $column->getName(), + $referenceTable->getNameWithoutPrefix(), + $referenceColumn->getName() + ); + } + + return $nameWithoutPrefix; + } +} diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php index 0e1ad0768c4da..040549a5611ca 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php @@ -7,6 +7,7 @@ use Magento\Framework\App\ResourceConnection; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\Declaration\TableElement\ElementNameResolver; use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** @@ -39,28 +40,36 @@ class Foreign implements FactoryInterface */ private $tableNameResolver; + /** + * @var ElementNameResolver + */ + private $elementNameResolver; + /** * Constructor. * * @param ObjectManagerInterface $objectManager * @param ResourceConnection $resourceConnection * @param TableNameResolver $tableNameResolver + * @param ElementNameResolver $elementNameResolver * @param string $className */ public function __construct( ObjectManagerInterface $objectManager, ResourceConnection $resourceConnection, TableNameResolver $tableNameResolver, + ElementNameResolver $elementNameResolver, $className = \Magento\Framework\Setup\Declaration\Schema\Dto\Constraints\Reference::class ) { $this->objectManager = $objectManager; $this->resourceConnection = $resourceConnection; $this->className = $className; $this->tableNameResolver = $tableNameResolver; + $this->elementNameResolver = $elementNameResolver; } /** - * {@inheritdoc} + * @inheritdoc */ public function create(array $data) { @@ -68,22 +77,13 @@ public function create(array $data) $data['onDelete'] = self::DEFAULT_ON_DELETE; } - $nameWithoutPrefix = $data['name']; - - if ($this->resourceConnection->getTablePrefix()) { - $nameWithoutPrefix = $this->resourceConnection - ->getConnection($data['table']->getResource()) - ->getForeignKeyName( - $this->tableNameResolver->getNameOfOriginTable( - $data['table']->getNameWithoutPrefix() - ), - $data['column']->getName(), - $data['referenceTable']->getNameWithoutPrefix(), - $data['referenceColumn']->getName() - ); - } - - $data['nameWithoutPrefix'] = $nameWithoutPrefix; + $data['nameWithoutPrefix'] = $this->elementNameResolver->getFKNameWithoutPrefix( + $data['name'], + $data['table'], + $data['column'], + $data['referenceTable'], + $data['referenceColumn'] + ); return $this->objectManager->create($this->className, $data); } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php index dd2acd7608867..715f98c4177c0 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php @@ -8,6 +8,7 @@ use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\Declaration\TableElement\ElementNameResolver; use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** @@ -40,28 +41,36 @@ class Index implements FactoryInterface */ private $tableNameResolver; + /** + * @var ElementNameResolver + */ + private $elementNameResolver; + /** * Constructor. * * @param ObjectManagerInterface $objectManager * @param ResourceConnection $resourceConnection * @param TableNameResolver $tableNameResolver + * @param ElementNameResolver $elementNameResolver * @param string $className */ public function __construct( ObjectManagerInterface $objectManager, ResourceConnection $resourceConnection, TableNameResolver $tableNameResolver, + ElementNameResolver $elementNameResolver, $className = \Magento\Framework\Setup\Declaration\Schema\Dto\Index::class ) { $this->objectManager = $objectManager; $this->resourceConnection = $resourceConnection; $this->className = $className; $this->tableNameResolver = $tableNameResolver; + $this->elementNameResolver = $elementNameResolver; } /** - * {@inheritdoc} + * @inheritdoc */ public function create(array $data) { @@ -69,29 +78,12 @@ public function create(array $data) $data['indexType'] = self::DEFAULT_INDEX_TYPE; } - $nameWithoutPrefix = $data['name']; - - if ($this->resourceConnection->getTablePrefix()) { - /** - * Temporary solution. - * @see MAGETWO-91365 - */ - $indexType = AdapterInterface::INDEX_TYPE_INDEX; - if ($data['indexType'] === AdapterInterface::INDEX_TYPE_FULLTEXT) { - $indexType = $data['indexType']; - } - $nameWithoutPrefix = $this->resourceConnection - ->getConnection($data['table']->getResource()) - ->getIndexName( - $this->tableNameResolver->getNameOfOriginTable( - $data['table']->getNameWithoutPrefix() - ), - $data['column'], - $indexType - ); - } - - $data['nameWithoutPrefix'] = $nameWithoutPrefix; + $data['nameWithoutPrefix'] = $this->elementNameResolver->getIndexNameWithoutPrefix( + $data['name'], + $data['table'], + $data['column'], + $data['indexType'] + ); return $this->objectManager->create($this->className, $data); } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php index 57e5270b0c82e..141e4a7083200 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php @@ -7,6 +7,7 @@ use Magento\Framework\App\ResourceConnection; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\Declaration\TableElement\ElementNameResolver; use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** @@ -34,46 +35,45 @@ class Unique implements FactoryInterface */ private $tableNameResolver; + /** + * @var ElementNameResolver + */ + private $elementNameResolver; + /** * Constructor. * * @param ObjectManagerInterface $objectManager * @param ResourceConnection $resourceConnection * @param TableNameResolver $tableNameResolver + * @param ElementNameResolver $elementNameResolver * @param string $className */ public function __construct( ObjectManagerInterface $objectManager, ResourceConnection $resourceConnection, TableNameResolver $tableNameResolver, + ElementNameResolver $elementNameResolver, $className = \Magento\Framework\Setup\Declaration\Schema\Dto\Constraints\Internal::class ) { $this->objectManager = $objectManager; $this->resourceConnection = $resourceConnection; $this->className = $className; $this->tableNameResolver = $tableNameResolver; + $this->elementNameResolver = $elementNameResolver; } /** - * {@inheritdoc} + * @inheritdoc */ public function create(array $data) { - $nameWithoutPrefix = $data['name']; - - if ($this->resourceConnection->getTablePrefix()) { - $nameWithoutPrefix = $this->resourceConnection - ->getConnection($data['table']->getResource()) - ->getIndexName( - $this->tableNameResolver->getNameOfOriginTable( - $data['table']->getNameWithoutPrefix() - ), - $data['column'], - $data['type'] - ); - } - - $data['nameWithoutPrefix'] = $nameWithoutPrefix; + $data['nameWithoutPrefix'] = $this->elementNameResolver->getIndexNameWithoutPrefix( + $data['name'], + $data['table'], + $data['column'], + $data['type'] + ); return $this->objectManager->create($this->className, $data); } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Table.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Table.php index 4f020b1a0320f..11111ea524212 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Table.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Table.php @@ -87,11 +87,11 @@ class Table extends GenericElement implements * @param string $engine * @param string $charset * @param string $collation + * @param string $onCreate * @param string|null $comment * @param array $columns * @param array $indexes * @param array $constraints - * @param string $onCreate * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -123,6 +123,7 @@ public function __construct( /** * Return different table constraints. + * * It can be constraint like unique key or reference to another table, etc * * @return Constraint[] @@ -133,6 +134,8 @@ public function getConstraints() } /** + * Provides constraint by name. + * * @param string $name * @return Constraint | bool */ @@ -191,6 +194,8 @@ public function getInternalConstraints() : array } /** + * Provides index by name. + * * @param string $name * @return Index | bool */ @@ -201,6 +206,7 @@ public function getIndexByName($name) /** * Return all columns. + * * Note, table always must have columns * * @return Column[] @@ -280,6 +286,7 @@ public function getColumnByName($nameOrId) /** * Retrieve elements by specific type + * * Allowed types: columns, constraints, indexes... * * @param string $type @@ -296,6 +303,7 @@ public function getElementsByType($type) /** * This is workaround, as any DTO object couldnt be changed after instantiation. + * * However there is case, when we depends on column definition we need modify our indexes * * @param array $indexes @@ -314,6 +322,8 @@ public function getElementType() } /** + * Retrieve engine name. + * * @return string */ public function getEngine(): string @@ -356,6 +366,8 @@ public function getCollation() : string } /** + * Retrieve the table name which is calculated without table prefix. + * * @return string */ public function getNameWithoutPrefix(): string @@ -364,6 +376,8 @@ public function getNameWithoutPrefix(): string } /** + * Retrieve table comment. + * * @return null|string */ public function getComment() diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd index d6436204a32e5..cd08e3f43ad43 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/index.xsd @@ -19,7 +19,7 @@ </xs:sequence> <xs:attribute name="indexType" type="indexType" /> - <xs:attribute name="referenceId" type="referenceIdType" /> + <xs:attribute name="referenceId" type="referenceIdType" use="required" /> <xs:attribute name="disabled" type="xs:boolean" /> </xs:complexType> diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd index 54c8f19753070..a2f8611c4bd33 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/schema.xsd @@ -39,9 +39,38 @@ <xs:element name="schema"> <xs:complexType> <xs:sequence minOccurs="0" maxOccurs="unbounded"> - <xs:element name="table" type="table"/> + <xs:element name="table" type="table"> + <xs:unique name="uniqueColumnName"> + <xs:annotation> + <xs:documentation>Column name be unique for each table</xs:documentation> + </xs:annotation> + <xs:selector xpath="column" /> + <xs:field xpath="@name" /> + </xs:unique> + <xs:unique name="uniqueIndexReferenceId"> + <xs:annotation> + <xs:documentation>Reference ID should be unique for indexes</xs:documentation> + </xs:annotation> + <xs:selector xpath="index" /> + <xs:field xpath="@referenceId" /> + </xs:unique> + <xs:unique name="uniqueConstraintReferenceId"> + <xs:annotation> + <xs:documentation>Reference ID should be unique for constraints</xs:documentation> + </xs:annotation> + <xs:selector xpath="constraint" /> + <xs:field xpath="@referenceId" /> + </xs:unique> + </xs:element> </xs:sequence> </xs:complexType> + <xs:unique name="uniqueTableName"> + <xs:annotation> + <xs:documentation>Table name should be unique for each module</xs:documentation> + </xs:annotation> + <xs:selector xpath="table" /> + <xs:field xpath="@name" /> + </xs:unique> </xs:element> <xs:complexType name="table"> From e17662c47d6cd51a21cdecd0064564ef0560575d Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 22 Oct 2018 10:53:34 -0500 Subject: [PATCH 422/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../revisions/whitelist_upgrade/db_schema.xml | 60 ++++++ .../revisions/whitelist_upgrade/db_schema.xml | 28 +++ .../TablesWhitelistGenerateCommandTest.php | 172 +++++------------- .../db_schema_whitelist.json | 80 ++++++++ .../db_schema_whitelist.json | 20 ++ 5 files changed, 238 insertions(+), 122 deletions(-) create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/whitelist_upgrade/db_schema.xml create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/whitelist_upgrade/db_schema.xml create mode 100644 dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule1/db_schema_whitelist.json create mode 100644 dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule8/db_schema_whitelist.json diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/whitelist_upgrade/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/whitelist_upgrade/db_schema.xml new file mode 100644 index 0000000000000..90eaf91b10743 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/whitelist_upgrade/db_schema.xml @@ -0,0 +1,60 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="reference_table" resource="default"> + <column xsi:type="tinyint" name="tinyint_ref" padding="7" nullable="false" identity="true" unsigned="false"/> + <column xsi:type="tinyint" name="tinyint_without_padding" default="0" nullable="false" unsigned="false"/> + <column xsi:type="bigint" name="bigint_without_padding" default="0" nullable="false" unsigned="false"/> + <column xsi:type="smallint" name="smallint_without_padding" default="0" nullable="false" unsigned="false"/> + <column xsi:type="int" name="integer_without_padding" default="0" nullable="false" unsigned="false"/> + <column xsi:type="smallint" name="smallint_with_big_padding" padding="254" default="0" nullable="false" + unsigned="false"/> + <column xsi:type="smallint" name="smallint_without_default" padding="2" nullable="true" unsigned="false"/> + <column xsi:type="int" name="int_without_unsigned" padding="2" nullable="true"/> + <column xsi:type="int" name="int_unsigned" padding="2" nullable="true" unsigned="true"/> + <column xsi:type="bigint" name="bigint_default_nullable" padding="2" nullable="true" default="1" + unsigned="true"/> + <column xsi:type="bigint" name="bigint_not_default_not_nullable" padding="2" nullable="false" unsigned="true"/> + <constraint xsi:type="primary" referenceId="tinyint_primary"> + <column name="tinyint_ref"/> + </constraint> + </table> + <table name="test_table" resource="default"> + <!--Columns--> + <column xsi:type="smallint" identity="true" name="smallint" padding="3" nullable="true"/> + <column xsi:type="tinyint" name="tinyint" padding="7" nullable="true" unsigned="false"/> + <column xsi:type="bigint" name="bigint" default="0" padding="13" nullable="true" unsigned="false"/> + <column xsi:type="float" name="float" default="0" scale="4" precision="12"/> + <column xsi:type="decimal" name="double" default="11111111.111111" precision="14" scale="6"/> + <column xsi:type="decimal" name="decimal" default="0" scale="4" precision="15"/> + <column xsi:type="date" name="date"/> + <column xsi:type="timestamp" name="timestamp" default="CURRENT_TIMESTAMP" on_update="true"/> + <column xsi:type="datetime" name="datetime" default="0"/> + <column xsi:type="longtext" name="longtext"/> + <column xsi:type="mediumtext" name="mediumtext"/> + <column xsi:type="varchar" name="varchar" length="254" nullable="true"/> + <column xsi:type="mediumblob" name="mediumblob"/> + <column xsi:type="blob" name="blob"/> + <column xsi:type="boolean" name="boolean"/> + <column xsi:type="varbinary" name="varbinary_rename" default="10101" disabled="true"/> + <!--Constraints--> + <constraint xsi:type="unique" referenceId="TEST_TABLE_UNIQUE"> + <column name="smallint"/> + <column name="bigint"/> + </constraint> + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE" + column="tinyint" table="test_table" + referenceTable="reference_table" referenceColumn="tinyint_ref" onDelete="NO ACTION"/> + <!--Indexes--> + <index referenceId="TEST_TABLE_INDEX" indexType="btree"> + <column name="tinyint"/> + <column name="bigint"/> + </index> + </table> +</schema> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/whitelist_upgrade/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/whitelist_upgrade/db_schema.xml new file mode 100644 index 0000000000000..05ce3318ef73b --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/whitelist_upgrade/db_schema.xml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="reference_test" resource="default"> + <column xsi:type="smallint" identity="true" name="entity_id" padding="3" nullable="true"/> + <column xsi:type="smallint" identity="true" name="product_id" padding="3" nullable="true"/> + <index referenceId="ENTITY_ID_INDEX" indexType="btree"> + <column name="entity_id"/> + </index> + <constraint xsi:type="unique" referenceId="UNIQUE_PAIR"> + <column name="entity_id"/> + <column name="product_id"/> + </constraint> + <constraint xsi:type="foreign" referenceId="TEST_TABLE_TINYINT_REFERENCE" + column="entity_id" table="reference_test" + referenceTable="test_table" referenceColumn="smallint" onDelete="NO ACTION"/> + </table> + <table name="auto_increment_test" resource="default"> + <column xsi:type="int" name="int_counter" padding="12" unsigned="true" + nullable="true"/> + </table> +</schema> diff --git a/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php b/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php index ef745d9e6fa4a..434c99cb98765 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Developer/Console/Command/TablesWhitelistGenerateCommandTest.php @@ -11,6 +11,7 @@ use Magento\TestFramework\TestCase\SetupTestCase; use Magento\Framework\Console\Cli; use Magento\TestFramework\Deploy\CliCommand; +use Magento\TestFramework\Deploy\TestModuleManager; /** * The purpose of this test is to verify the declaration:generate:whitelist command. @@ -42,6 +43,11 @@ class TablesWhitelistGenerateCommandTest extends SetupTestCase */ private $cliCommand; + /** + * @var TestModuleManager + */ + private $moduleManager; + /** * {@inheritdoc} */ @@ -56,21 +62,43 @@ public function setUp() ); $this->cliCommand = $this->objectManager->get(CliCommand::class); $this->tester = new CommandTester($this->command); + $this->moduleManager = $this->objectManager->get(TestModuleManager::class); } /** - * Execute generate command for whitelist on module Magento_TestSetupDeclarationModule1. - * - * @param array $expectedWhitelistContent + * Execute generate command for whitelist. * * @moduleName Magento_TestSetupDeclarationModule1 - * @dataProvider contentsDataProvider + * @moduleName Magento_TestSetupDeclarationModule8 * @throws \Exception */ - public function testExecute(array $expectedWhitelistContent) + public function testExecute() + { + $modules = [ + 'Magento_TestSetupDeclarationModule1', + 'Magento_TestSetupDeclarationModule8', + ]; + + $this->cliCommand->install($modules); + foreach ($modules as $moduleName) { + $this->moduleManager->updateRevision( + $moduleName, + 'whitelist_upgrade', + 'db_schema.xml', + 'etc' + ); + } + + foreach ($modules as $moduleName) { + $this->checkWhitelistFile($moduleName); + } + } + + /** + * @param string $moduleName + */ + private function checkWhitelistFile(string $moduleName) { - $moduleName = 'Magento_TestSetupDeclarationModule1'; - $this->cliCommand->install([$moduleName]); $modulePath = $this->componentRegistrar->getPath('module', $moduleName); $whiteListFileName = $modulePath . DIRECTORY_SEPARATOR @@ -80,125 +108,25 @@ public function testExecute(array $expectedWhitelistContent) //run bin/magento declaration:generate:whitelist Magento_TestSetupDeclarationModule1 command. $this->tester->execute(['--module-name' => $moduleName], ['interactive' => false]); - $this->assertSame(Cli::RETURN_SUCCESS, $this->tester->getStatusCode()); $this->assertFileExists($whiteListFileName); $this->assertContains('', $this->tester->getDisplay()); - $whitelistContent = json_decode(file_get_contents($whiteListFileName), true); - $this->assertEquals($expectedWhitelistContent, $whitelistContent); - } - - /** - * Data provider for whitelist contents. - * - * @return array - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function contentsDataProvider(): array - { - return [ - [ - 'content' => [ - 'reference_table' => - [ - 'column' => - [ - 'tinyint_ref' => true, - 'tinyint_without_padding' => true, - 'bigint_without_padding' => true, - 'integer_without_padding' => true, - 'smallint_with_big_padding' => true, - 'smallint_without_default' => true, - 'int_without_unsigned' => true, - 'int_unsigned' => true, - 'bigint_default_nullable' => true, - 'bigint_not_default_not_nullable' => true, - 'smallint_without_padding' => true, - ], - 'constraint' => - [ - 'tinyint_primary' => true, - 'PRIMARY' => true, - ], - ], - 'auto_increment_test' => - [ - 'column' => - [ - 'int_auto_increment_with_nullable' => true, - 'int_disabled_auto_increment' => true, - ], - 'constraint' => - [ - 'AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE' => true, - ], - ], - 'test_table' => - [ - 'column' => - [ - 'smallint' => true, - 'tinyint' => true, - 'bigint' => true, - 'float' => true, - 'double' => true, - 'decimal' => true, - 'date' => true, - 'timestamp' => true, - 'datetime' => true, - 'longtext' => true, - 'mediumtext' => true, - 'varchar' => true, - 'mediumblob' => true, - 'blob' => true, - 'boolean' => true, - 'varbinary_rename' => true, - ], - 'index' => - [ - 'TEST_TABLE_TINYINT_BIGINT' => true, - ], - 'constraint' => - [ - 'TEST_TABLE_SMALLINT_BIGINT' => true, - 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF' => true, - ], - ], - 'store' => - [ - 'column' => - [ - 'store_owner_id' => true, - 'store_owner' => true, - ], - 'constraint' => - [ - 'STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID' => true, - ], - ], - 'store_owner' => - [ - 'column' => - [ - 'owner_id' => true, - 'label' => true, - ], - 'constraint' => - [ - '' => true, - ], - ], - 'some_table' => - [ - 'column' => - [ - 'some_column' => true, - ], - ], - ], - ], - ]; + $whitelistFileContent = file_get_contents($whiteListFileName); + $expectedWhitelistContent = file_get_contents( + dirname(__DIR__, 2) + . DIRECTORY_SEPARATOR + . implode( + DIRECTORY_SEPARATOR, + [ + '_files', + 'WhitelistGenerate', + str_replace('Magento_', '', $moduleName), + 'db_schema_whitelist.json' + ] + ) + ); + $this->assertEquals($expectedWhitelistContent, $whitelistFileContent); } } diff --git a/dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule1/db_schema_whitelist.json b/dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule1/db_schema_whitelist.json new file mode 100644 index 0000000000000..55005b82ab8b5 --- /dev/null +++ b/dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule1/db_schema_whitelist.json @@ -0,0 +1,80 @@ +{ + "reference_table": { + "column": { + "tinyint_ref": true, + "tinyint_without_padding": true, + "bigint_without_padding": true, + "integer_without_padding": true, + "smallint_with_big_padding": true, + "smallint_without_default": true, + "int_without_unsigned": true, + "int_unsigned": true, + "bigint_default_nullable": true, + "bigint_not_default_not_nullable": true, + "smallint_without_padding": true + }, + "constraint": { + "tinyint_primary": true, + "PRIMARY": true + } + }, + "auto_increment_test": { + "column": { + "int_auto_increment_with_nullable": true, + "int_disabled_auto_increment": true + }, + "constraint": { + "AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE": true + } + }, + "test_table": { + "column": { + "smallint": true, + "tinyint": true, + "bigint": true, + "float": true, + "double": true, + "decimal": true, + "date": true, + "timestamp": true, + "datetime": true, + "longtext": true, + "mediumtext": true, + "varchar": true, + "mediumblob": true, + "blob": true, + "boolean": true, + "varbinary_rename": true + }, + "index": { + "TEST_TABLE_TINYINT_BIGINT": true + }, + "constraint": { + "TEST_TABLE_SMALLINT_BIGINT": true, + "TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF": true + } + }, + "store": { + "column": { + "store_owner_id": true, + "store_owner": true + }, + "constraint": { + "STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID": true + } + }, + "store_owner": { + "column": { + "owner_id": true, + "label": true + }, + "constraint": { + "": true + } + }, + "some_table": { + "column": { + "some_column": true + } + } +} \ No newline at end of file diff --git a/dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule8/db_schema_whitelist.json b/dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule8/db_schema_whitelist.json new file mode 100644 index 0000000000000..b4209edfe471a --- /dev/null +++ b/dev/tests/setup-integration/testsuite/Magento/Developer/_files/WhitelistGenerate/TestSetupDeclarationModule8/db_schema_whitelist.json @@ -0,0 +1,20 @@ +{ + "reference_test": { + "column": { + "entity_id": true, + "product_id": true + }, + "index": { + "REFERENCE_TEST_ENTITY_ID": true + }, + "constraint": { + "REFERENCE_TEST_ENTITY_ID_PRODUCT_ID": true, + "REFERENCE_TEST_ENTITY_ID_TEST_TABLE_SMALLINT": true + } + }, + "auto_increment_test": { + "column": { + "int_counter": true + } + } +} \ No newline at end of file From e97e0e08bff18bc84f01ce0e9ad6aee7ef70860a Mon Sep 17 00:00:00 2001 From: Sergey Shvets <sshvets@magento.com> Date: Mon, 22 Oct 2018 17:46:44 +0300 Subject: [PATCH 423/812] MAGETWO-95739: Zip code is not validated during checkout when "My billing and shipping address are the same" is unchecked --- .../web/js/model/shipping-rates-validator.js | 16 +++++++++------- .../view/frontend/web/js/view/billing-address.js | 9 +++++++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js index d31c0dca38116..ca11fec7cd5a0 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js @@ -35,7 +35,6 @@ define([ var checkoutConfig = window.checkoutConfig, validators = [], observedElements = [], - postcodeElement = null, postcodeElementName = 'postcode'; validators.push(defaultValidator); @@ -79,7 +78,11 @@ define([ } $.each(elements, function (index, field) { - uiRegistry.async(formPath + '.' + field)(self.doElementBinding.bind(self)); + var elementBinding = self.doElementBinding.bind(self), + fullPath = formPath + '.' + field, + func = uiRegistry.async(fullPath); + + func(elementBinding); }); }, @@ -101,7 +104,6 @@ define([ if (element.index === postcodeElementName) { this.bindHandler(element, delay); - postcodeElement = element; } }, @@ -136,7 +138,7 @@ define([ if (!formPopUpState.isVisible()) { clearTimeout(self.validateAddressTimeout); self.validateAddressTimeout = setTimeout(function () { - self.postcodeValidation(); + self.postcodeValidation(element); self.validateFields(); }, delay); } @@ -148,7 +150,7 @@ define([ /** * @return {*} */ - postcodeValidation: function () { + postcodeValidation: function (postcodeElement) { var countryId = $('select[name="country_id"]').val(), validationResult, warnMessage; @@ -178,8 +180,8 @@ define([ */ validateFields: function () { var addressFlat = addressConverter.formDataProviderToFlatData( - this.collectObservedData(), - 'shippingAddress' + this.collectObservedData(), + 'shippingAddress' ), address; diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js index 6b5d08c2641cc..6a2f329d095d6 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js @@ -17,7 +17,8 @@ define([ 'Magento_Customer/js/customer-data', 'Magento_Checkout/js/action/set-billing-address', 'Magento_Ui/js/model/messageList', - 'mage/translate' + 'mage/translate', + 'Magento_Checkout/js/model/shipping-rates-validator' ], function ( ko, @@ -33,7 +34,8 @@ function ( customerData, setBillingAddressAction, globalMessageList, - $t + $t, + shippingRatesValidator ) { 'use strict'; @@ -71,6 +73,9 @@ function ( quote.paymentMethod.subscribe(function () { checkoutDataResolver.resolveBillingAddress(); }, this); + shippingRatesValidator.initFields( + 'checkout.steps.billing-step.payment.payments-list.checkmo-form.form-fields' + ); }, /** From a8094985b44a5ece2c020021f040ef1aa7b535d1 Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@adobe.com> Date: Mon, 22 Oct 2018 11:19:22 -0500 Subject: [PATCH 424/812] MAGETWO-95595: Index names are ignored by declarative schema - test disable index --- .../db_schema.xml | 13 ++++++++++ .../Setup/DeclarativeInstallerTest.php | 25 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml new file mode 100644 index 0000000000000..a064678394e1a --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="test_table" resource="default"> + <index referenceId="TEST_TABLE_TINYINT_BIGINT" disabled="1"/> + </table> +</schema> diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php index 33f4b170637c2..4145584f6e48f 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php @@ -317,4 +317,29 @@ public function testForeignKeyReferenceId() $this->assertRegExp('/CONSTRAINT\s`DEPENDENT_PAGE_ID_ON_TEST_TABLE_PAGE_ID`/', $tableSql); $this->assertRegExp('/CONSTRAINT\s`DEPENDENT_SCOPE_ID_ON_TEST_SCOPE_TABLE_SCOPE_ID`/', $tableSql); } + + /** + * @moduleName Magento_TestSetupDeclarationModule1 + * @moduleName Magento_TestSetupDeclarationModule8 + */ + public function testDisableIndexByExternalModule() + { + $this->cliCommad->install( + ['Magento_TestSetupDeclarationModule1', 'Magento_TestSetupDeclarationModule8'] + ); + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule8', + 'disable_index_by_external_module', + 'db_schema.xml', + 'etc' + ); + $this->cliCommad->upgrade(); + $tableStatements = $this->describeTable->describeShard('default'); + $tableSql = $tableStatements['test_table']; + $this->assertNotRegExp( + '/KEY\s+`TEST_TABLE_TINYINT_BIGINT`\s+\(`tinyint`,`bigint`\)/', + $tableSql, + 'Index is not being disabled by external module' + ); + } } From 4e7ad4e90b5d8e031ab8b9e8a7bcbf153eeba4e6 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 22 Oct 2018 11:28:41 -0500 Subject: [PATCH 425/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../TestModuleDefaultHydrator/etc/db_schema.xml | 4 ++-- .../fixture/valid_xml_revision_1.php | 12 ++++++------ .../Db/MySQL/Definition/Constraints/ForeignKey.php | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/dev/tests/api-functional/_files/Magento/TestModuleDefaultHydrator/etc/db_schema.xml b/dev/tests/api-functional/_files/Magento/TestModuleDefaultHydrator/etc/db_schema.xml index d9bba3ca5dbe8..3c71e2fde48fa 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleDefaultHydrator/etc/db_schema.xml +++ b/dev/tests/api-functional/_files/Magento/TestModuleDefaultHydrator/etc/db_schema.xml @@ -11,10 +11,10 @@ <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="true"/> <column xsi:type="int" name="customer_id" padding="10" unsigned="true" nullable="false" identity="false"/> <column xsi:type="varchar" name="value" nullable="true" length="255"/> - <constraint xsi:type="primary" name="PRIMARY"> + <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="entity_id"/> </constraint> - <constraint xsi:type="foreign" name="CSTR_EXTENSION_ATTR_ENTT_CSTR_ID_CSTR_ENTT_ENTT_ID" + <constraint xsi:type="foreign" referenceId="CSTR_EXTENSION_ATTR_ENTT_CSTR_ID_CSTR_ENTT_ENTT_ID" table="testmodule_default_hydrator_extension_attribute_entity" column="customer_id" referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/> </table> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php index 7271103e3e721..a064d096f6d38 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php @@ -225,17 +225,17 @@ ], ], 'constraint' => [ - 'TEST_TABLE_SMALLINT_BIGINT' => [ + 'TEST_TABLE_UNIQUE' => [ 'column' => [ 'smallint' => 'smallint', 'bigint' => 'bigint', ], 'type' => 'unique', - 'referenceId' => 'TEST_TABLE_SMALLINT_BIGINT', + 'referenceId' => 'TEST_TABLE_UNIQUE', ], - 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF' => [ + 'TEST_TABLE_TINYINT_REFERENCE' => [ 'type' => 'foreign', - 'referenceId' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', + 'referenceId' => 'TEST_TABLE_TINYINT_REFERENCE', 'column' => 'tinyint', 'table' => 'test_table', 'referenceTable' => 'reference_table', @@ -244,12 +244,12 @@ ], ], 'index' => [ - 'TEST_TABLE_TINYINT_BIGINT' => [ + 'TEST_TABLE_INDEX' => [ 'column' => [ 'tinyint' => 'tinyint', 'bigint' => 'bigint', ], - 'referenceId' => 'TEST_TABLE_TINYINT_BIGINT', + 'referenceId' => 'TEST_TABLE_INDEX', 'indexType' => 'btree', ], ], diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php index 26bc2209d01ec..6d11542bb49d3 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Db/MySQL/Definition/Constraints/ForeignKey.php @@ -43,7 +43,6 @@ public function __construct(ResourceConnection $resourceConnection) } /** - * @param Reference $foreignKey * @inheritdoc */ public function toDefinition(ElementInterface $foreignKey) From 0225c686065f219a4db02c4000cf5c0562b08874 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Mon, 22 Oct 2018 11:48:33 -0500 Subject: [PATCH 426/812] MAGETWO-95799: [Flaky test]Stabilize AdminAddImageToCMSPageTinyMCE3Test - stabilize test --- .../Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 793af65be9d66..9d3b498dc6ce6 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -17,9 +17,6 @@ <description value="Verify that admin is able to upload image to CMS Page with TinyMCE3 enabled"/> <severity value="MAJOR"/> <testCaseId value="MAGETWO-95725"/> - <skip> - <issueId value="MAGETWO-95799"/> - </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From d76cc54ef23c9f2eec8cc6c832ab16dbb23a6f17 Mon Sep 17 00:00:00 2001 From: Roman Ganin <rganin@adobe.com> Date: Mon, 22 Oct 2018 11:50:00 -0500 Subject: [PATCH 427/812] MAGETWO-95595: Index names are ignored by declarative schema - test disable index --- .../etc/db_schema.xml | 3 ++ .../revisions/index_to_disable/db_schema.xml | 30 +++++++++++++++++++ .../db_schema.xml | 2 +- .../db_schema_whitelist.json | 7 +++++ .../module.xml | 14 +++++++++ .../Setup/DeclarativeInstallerTest.php | 20 ++++++++++++- 6 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/index_to_disable/db_schema.xml create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema_whitelist.json create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/module.xml diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml index ae6c98e4627d2..30cb5b4d166ad 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml @@ -65,5 +65,8 @@ <column name="tinyint"/> <column name="bigint"/> </index> + <index referenceId="TEST_TABLE_INDEX_VARCHAR" indexType="btree"> + <column name="varchar"/> + </index> </table> </schema> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/index_to_disable/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/index_to_disable/db_schema.xml new file mode 100644 index 0000000000000..e10803af248c2 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/index_to_disable/db_schema.xml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="test_table" resource="default"> + <!--Columns--> + <column xsi:type="smallint" identity="true" name="smallint" padding="3" nullable="true"/> + <column xsi:type="tinyint" name="tinyint" padding="7" nullable="true" unsigned="false"/> + <column xsi:type="bigint" name="bigint" default="0" padding="13" nullable="true" unsigned="false"/> + <column xsi:type="varchar" name="varchar" length="254" nullable="true"/> + <!--Constraints--> + <constraint xsi:type="unique" referenceId="TEST_TABLE_UNIQUE"> + <column name="smallint"/> + <column name="bigint"/> + </constraint> + <!--Indexes--> + <index referenceId="TEST_TABLE_INDEX" indexType="btree"> + <column name="tinyint"/> + <column name="bigint"/> + </index> + <index referenceId="TEST_TABLE_INDEX_VARCHAR" indexType="btree"> + <column name="varchar"/> + </index> + </table> +</schema> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml index a064678394e1a..f8860731aa808 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema.xml @@ -8,6 +8,6 @@ <schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="test_table" resource="default"> - <index referenceId="TEST_TABLE_TINYINT_BIGINT" disabled="1"/> + <index referenceId="TEST_TABLE_INDEX_VARCHAR" disabled="1"/> </table> </schema> diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema_whitelist.json b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema_whitelist.json new file mode 100644 index 0000000000000..a65bb6aab1c43 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/db_schema_whitelist.json @@ -0,0 +1,7 @@ +{ + "test_table": { + "index": { + "TEST_TABLE_VARCHAR": true + } + } +} diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/module.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/module.xml new file mode 100644 index 0000000000000..a0b9bbe483bcf --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule8/revisions/disable_index_by_external_module/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_TestSetupDeclarationModule8"> + <sequence> + <module name="Magento_TestSetupDeclarationModule1" /> + </sequence> + </module> +</config> diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php index bf50a5a29821e..f6497e8e4b162 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php @@ -343,17 +343,35 @@ public function testDisableIndexByExternalModule() $this->cliCommad->install( ['Magento_TestSetupDeclarationModule1', 'Magento_TestSetupDeclarationModule8'] ); + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule1', + 'index_to_disable', + 'db_schema.xml', + 'etc' + ); $this->moduleManager->updateRevision( 'Magento_TestSetupDeclarationModule8', 'disable_index_by_external_module', 'db_schema.xml', 'etc' ); + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule8', + 'disable_index_by_external_module', + 'db_schema_whitelist.json', + 'etc' + ); + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule8', + 'disable_index_by_external_module', + 'module.xml', + 'etc' + ); $this->cliCommad->upgrade(); $tableStatements = $this->describeTable->describeShard('default'); $tableSql = $tableStatements['test_table']; $this->assertNotRegExp( - '/KEY\s+`TEST_TABLE_TINYINT_BIGINT`\s+\(`tinyint`,`bigint`\)/', + '/KEY\s+`TEST_TABLE_VARCHAR`\s+\(`varchar`\)/', $tableSql, 'Index is not being disabled by external module' ); From 27fef74756ce331b5ab5da8457d3edd55ba71a63 Mon Sep 17 00:00:00 2001 From: Patrick Maguire <p.maguire@sumoheavy.com> Date: Mon, 22 Oct 2018 13:10:11 -0400 Subject: [PATCH 428/812] language cleanup on customer actions --- app/code/Magento/Customer/i18n/en_US.csv | 4 ++-- .../Customer/view/adminhtml/ui_component/customer_listing.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Customer/i18n/en_US.csv b/app/code/Magento/Customer/i18n/en_US.csv index bf73d6361d4c7..578267984f985 100644 --- a/app/code/Magento/Customer/i18n/en_US.csv +++ b/app/code/Magento/Customer/i18n/en_US.csv @@ -506,10 +506,10 @@ Strong,Strong "Rebuild Customer grid index","Rebuild Customer grid index" Group,Group "Add New Customer","Add New Customer" -"Are you sure to delete selected customers?","Are you sure to delete selected customers?" +"Are you sure you want to delete the selected customers?","Are you sure you want to delete the selected customers?" "Delete items","Delete items" "Subscribe to Newsletter","Subscribe to Newsletter" -"Are you sure to unsubscribe selected customers from newsletter?","Are you sure to unsubscribe selected customers from newsletter?" +"Are you sure you want to unsubscribe the selected customers from the newsletter?","Are you sure you want to unsubscribe the selected customers from the newsletter?" "Unsubscribe from Newsletter","Unsubscribe from Newsletter" "Assign a Customer Group","Assign a Customer Group" Phone,Phone diff --git a/app/code/Magento/Customer/view/adminhtml/ui_component/customer_listing.xml b/app/code/Magento/Customer/view/adminhtml/ui_component/customer_listing.xml index f8aa078f45e4d..6b479ad1cb290 100644 --- a/app/code/Magento/Customer/view/adminhtml/ui_component/customer_listing.xml +++ b/app/code/Magento/Customer/view/adminhtml/ui_component/customer_listing.xml @@ -49,7 +49,7 @@ <action name="delete"> <settings> <confirm> - <message translate="true">Are you sure to delete selected customers?</message> + <message translate="true">Are you sure you want to delete the selected customers?</message> <title translate="true">Delete items @@ -67,7 +67,7 @@ - Are you sure to unsubscribe selected customers from newsletter? + Are you sure you want to unsubscribe the selected customers from the newsletter? Unsubscribe from Newsletter From 97b519cafff9638d9455d9dc2e0aaca3704d805b Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Mon, 22 Oct 2018 19:19:21 +0200 Subject: [PATCH 429/812] Introduced cart address resolver and data provider --- .../Resolver/Address/AddressDataProvider.php | 70 +++++++++++++++ .../Model/Resolver/CartAddress.php | 87 +++++++++++++++++++ .../SetShippingMethodsOnCart.php | 6 +- .../Magento/QuoteGraphQl/etc/schema.graphqls | 22 ++--- 4 files changed, 173 insertions(+), 12 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php new file mode 100644 index 0000000000000..d401f296cb465 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php @@ -0,0 +1,70 @@ +dataObjectConverter = $dataObjectConverter; + } + + /** + * Collect and return information about shipping and billing addresses + * + * @param CartInterface $cart + * @return array + */ + public function getCartAddresses(CartInterface $cart): array + { + $addressData = []; + $shippingAddress = $cart->getShippingAddress(); + $billingAddress = $cart->getBillingAddress(); + + if ($shippingAddress) { + $shippingData = $this->dataObjectConverter->toFlatArray($shippingAddress, [], AddressInterface::class); + $shippingData['address_type'] = 'SHIPPING'; + $shippingData['selected_shipping_method'] = [ + 'code' => $shippingAddress->getShippingMethod(), + 'label' => $shippingAddress->getShippingDescription(), + 'free_shipping' => $shippingAddress->getFreeShipping(), + ]; + $shippingData['items_weight'] = $shippingAddress->getWeight(); + $shippingData['customer_notes'] = $shippingAddress->getCustomerNotes(); + $addressData[] = $shippingData; + } + + if ($billingAddress) { + $billingData = $this->dataObjectConverter->toFlatArray($billingAddress, [], AddressInterface::class); + $billingData['address_type'] = 'BILLING'; + $addressData[] = $billingData; + } + + return $addressData; + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php new file mode 100644 index 0000000000000..f83a112ba5ba8 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php @@ -0,0 +1,87 @@ +maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; + $this->cartRepository = $cartRepository; + $this->addressDataProvider = $addressDataProvider; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + if (!isset($value['cart_id'])) { + // TODO: consider the possibility to pass quote model instead od quote ID + throw new LocalizedException(__('"cart_id" value should be specified')); + } + + try { + $quoteId = $this->maskedQuoteIdToQuoteId->execute($value['cart_id']); + } catch (NoSuchEntityException $exception) { + throw new GraphQlNoSuchEntityException( + __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $value['cart_id']]) + ); + } + + // TODO: should we check customer permissions here as well? + + try { + $quote = $this->cartRepository->get($quoteId); + } catch (NoSuchEntityException $exception) { + throw new GraphQlNoSuchEntityException( + __('Could not find a cart with ID "%quote_id"', ['quote_id' => $quoteId]) + ); + } + + return $this->addressDataProvider->getCartAddresses($quote); + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php index c2d14668a2e70..1f35f37d9cf23 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php @@ -158,6 +158,10 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value throw new GraphQlInputException(__($exception->getMessage())); } - return 'Success!'; // TODO we should return cart here + return [ + 'cart' => [ + 'cart_id' => $maskedCartId + ] + ]; } } diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 730a54377b370..cbc56bfaea66f 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -67,7 +67,7 @@ type SetShippingAddressesOnCartOutput { } type SetShippingMethodsOnCartOutput { - cart: String #TODO: temp placeholder, should be Cart! + cart: Cart! } # If no address is provided, the system get address assigned to a quote @@ -92,28 +92,28 @@ type ApplyCouponToCartOutput { } type Cart { + cart_id: String items: [CartItemInterface] applied_coupon: AppliedCoupon - addresses: [CartAddress]! + addresses: [CartAddress]! @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartAddress") } type CartAddress { - firstname: String! - lastname: String! + firstname: String + lastname: String company: String - street: [String!]! - city: String! + street: [String] + city: String region: CartAddressRegion postcode: String - country: CartAddressCountry! - telephone: String! - address_type: AdressTypeEnum! + country: CartAddressCountry + telephone: String + address_type: AdressTypeEnum selected_shipping_method: CheckoutShippingMethod - available_shipping_methods: [CheckoutShippingMethod]! + available_shipping_methods: [CheckoutShippingMethod] items_weight: Float customer_notes: String cart_items: [CartItemQuantity] - applied_coupon: AppliedCoupon } type CartItemQuantity { From 78accc5569841afc37788f45847f11b52c0526c7 Mon Sep 17 00:00:00 2001 From: Mahesh Singh Date: Mon, 22 Oct 2018 23:36:21 +0530 Subject: [PATCH 430/812] issue #18655 fixed --- app/code/Magento/Integration/etc/adminhtml/system.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Integration/etc/adminhtml/system.xml b/app/code/Magento/Integration/etc/adminhtml/system.xml index 5abec8efbfdd6..fe80fe105493a 100644 --- a/app/code/Magento/Integration/etc/adminhtml/system.xml +++ b/app/code/Magento/Integration/etc/adminhtml/system.xml @@ -54,7 +54,7 @@ Maximum Number of authentication failures to lock out account. - + Period of time in seconds after which account will be unlocked. From b9af73aac043f0f19786ce5959c464aa857f2044 Mon Sep 17 00:00:00 2001 From: Max Lesechko Date: Mon, 22 Oct 2018 13:52:55 -0500 Subject: [PATCH 431/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../Declaration/Schema/WhitelistGenerator.php | 2 +- .../TablesWhitelistGenerateCommandTest.php | 425 ------------------ .../Schema/Config/ConverterTest.php | 6 +- .../Schema/Db/SchemaBuilderTest.php | 8 +- .../Schema/Dto/Factories/ForeignTest.php | 187 -------- 5 files changed, 9 insertions(+), 619 deletions(-) delete mode 100644 app/code/Magento/Developer/Test/Unit/Console/Command/TablesWhitelistGenerateCommandTest.php delete mode 100644 lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php diff --git a/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php b/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php index af20619934d68..b57abaf816f19 100644 --- a/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php +++ b/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php @@ -255,4 +255,4 @@ private function filterPrimaryTables(array $moduleDbSchema): array } return $moduleDbSchema; } -} \ No newline at end of file +} diff --git a/app/code/Magento/Developer/Test/Unit/Console/Command/TablesWhitelistGenerateCommandTest.php b/app/code/Magento/Developer/Test/Unit/Console/Command/TablesWhitelistGenerateCommandTest.php deleted file mode 100644 index 5bfc5686b05fb..0000000000000 --- a/app/code/Magento/Developer/Test/Unit/Console/Command/TablesWhitelistGenerateCommandTest.php +++ /dev/null @@ -1,425 +0,0 @@ -componentRegistrarMock = $this->getMockBuilder(ComponentRegistrar::class) - ->disableOriginalConstructor() - ->getMock(); - $this->readerCompositeMock = $this->getMockBuilder(ReaderComposite::class) - ->disableOriginalConstructor() - ->getMock(); - $this->jsonPersistorMock = $this->getMockBuilder(JsonPersistor::class) - ->getMock(); - $this->objectManagerHelper = new ObjectManagerHelper($this); - $this->model = $this->objectManagerHelper->getObject( - TablesWhitelistGenerateCommand::class, - [ - 'componentRegistrar' => $this->componentRegistrarMock, - 'readerComposite' => $this->readerCompositeMock, - 'jsonPersistor' => $this->jsonPersistorMock - ] - ); - } - - /** - * @return array - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function whitelistTableProvider() - { - return [ - [ - 'moduleName' => 'SomeModule', - 'whitelist' => [ - 'primary' => [ - 'table' => - [ - 'patch_list' => - [ - 'column' => - [ - 'patch_id' => - [ - 'type' => 'int', - 'name' => 'patch_id', - 'identity' => 'true', - 'comment' => 'Patch Auto Increment', - ], - 'patch_name' => - [ - 'type' => 'varchar', - 'name' => 'patch_name', - 'length' => '1024', - 'nullable' => 'false', - 'comment' => 'Patch Class Name', - ], - ], - 'constraint' => - [ - 'PRIMARY' => - [ - 'column' => - [ - 'patch_id' => 'patch_id', - ], - 'type' => 'primary', - 'name' => 'PRIMARY', - ], - ], - 'name' => 'patch_list', - 'resource' => 'default', - 'comment' => 'List of data/schema patches', - ], - ], - ], - 'SomeModule' => [ - 'table' => [ - 'first_table' => [ - 'disabled' => false, - 'name' => 'first_table', - 'resource' => 'default', - 'engine' => 'innodb', - 'column' => [ - 'first_column' => [ - 'name' => 'first_column', - 'xsi:type' => 'integer', - 'nullable' => 1, - 'unsigned' => '0', - ], - 'second_column' => [ - 'name' => 'second_column', - 'xsi:type' => 'date', - 'nullable' => 0, - ] - ], - 'index' => [ - 'TEST_INDEX' => [ - 'name' => 'TEST_INDEX', - 'indexType' => 'btree', - 'columns' => [ - 'first_column' - ] - ] - ], - 'constraint' => [ - 'foreign' => [ - 'some_foreign_constraint' => [ - 'referenceTable' => 'table', - 'referenceColumn' => 'column', - 'table' => 'first_table', - 'column' => 'first_column' - ] - ], - 'primary' => [ - 'PRIMARY' => [ - 'xsi:type' => 'primary', - 'name' => 'PRIMARY', - 'columns' => [ - 'second_column' - ] - ] - ] - ] - ] - ] - ], - ], - 'expected' => [ - 'SomeModule' => [ - 'first_table' => [ - 'column' => [ - 'first_column' => true, - 'second_column' => true, - ], - 'index' => [ - 'TEST_INDEX' => true, - ], - 'constraint' => [ - 'foreign' => true, - 'primary' => true, - ] - ] - ] - ] - ], - [ - 'moduleName' => false, - 'whitelist' => [ - 'primary' => [ - 'table' => - [ - 'patch_list' => - [ - 'column' => - [ - 'patch_id' => - [ - 'type' => 'int', - 'name' => 'patch_id', - 'identity' => 'true', - 'comment' => 'Patch Auto Increment', - ], - 'patch_name' => - [ - 'type' => 'varchar', - 'name' => 'patch_name', - 'length' => '1024', - 'nullable' => 'false', - 'comment' => 'Patch Class Name', - ], - ], - 'constraint' => - [ - 'PRIMARY' => - [ - 'column' => - [ - 'patch_id' => 'patch_id', - ], - 'type' => 'primary', - 'name' => 'PRIMARY', - ], - ], - 'name' => 'patch_list', - 'resource' => 'default', - 'comment' => 'List of data/schema patches', - ], - ], - ], - 'SomeModule' => [ - 'table' => [ - 'first_table' => [ - 'disabled' => false, - 'name' => 'first_table', - 'resource' => 'default', - 'engine' => 'innodb', - 'column' => [ - 'first_column' => [ - 'name' => 'first_column', - 'xsi:type' => 'integer', - 'nullable' => 1, - 'unsigned' => '0', - ], - 'second_column' => [ - 'name' => 'second_column', - 'xsi:type' => 'date', - 'nullable' => 0, - ] - ], - 'index' => [ - 'TEST_INDEX' => [ - 'name' => 'TEST_INDEX', - 'indexType' => 'btree', - 'columns' => [ - 'first_column' - ] - ] - ], - 'constraint' => [ - 'foreign' => [ - 'some_foreign_constraint' => [ - 'referenceTable' => 'table', - 'referenceColumn' => 'column', - 'table' => 'first_table', - 'column' => 'first_column' - ] - ], - 'primary' => [ - 'PRIMARY' => [ - 'xsi:type' => 'primary', - 'name' => 'PRIMARY', - 'columns' => [ - 'second_column' - ] - ] - ] - ] - ] - ] - ], - 'Module2' => [ - 'table' => [ - 'second_table' => [ - 'disabled' => false, - 'name' => 'second_table', - 'resource' => 'default', - 'engine' => 'innodb', - 'column' => [ - 'first_column' => [ - 'name' => 'first_column', - 'xsi:type' => 'integer', - 'nullable' => 1, - 'unsigned' => '0', - ], - 'second_column' => [ - 'name' => 'second_column', - 'xsi:type' => 'date', - 'nullable' => 0, - ] - ], - 'index' => [ - 'TEST_INDEX' => [ - 'name' => 'TEST_INDEX', - 'indexType' => 'btree', - 'columns' => [ - 'first_column' - ] - ] - ], - 'constraint' => [ - 'foreign' => [ - 'some_foreign_constraint' => [ - 'referenceTable' => 'table', - 'referenceColumn' => 'column', - 'table' => 'second_table', - 'column' => 'first_column' - ] - ], - 'primary' => [ - 'PRIMARY' => [ - 'xsi:type' => 'primary', - 'name' => 'PRIMARY', - 'columns' => [ - 'second_column' - ] - ] - ] - ] - ] - ] - ] - ], - 'expected' => [ - 'SomeModule' => [ - 'first_table' => [ - 'column' => [ - 'first_column' => true, - 'second_column' => true, - ], - 'index' => [ - 'TEST_INDEX' => true, - ], - 'constraint' => [ - 'foreign' => true, - 'primary' => true, - ] - ] - ], - 'Module2' => [ - 'second_table' => [ - 'column' => [ - 'first_column' => true, - 'second_column' => true, - ], - 'index' => [ - 'TEST_INDEX' => true, - ], - 'constraint' => [ - 'foreign' => true, - 'primary' => true, - ] - ] - ] - ] - ] - ]; - } - - /** - * @dataProvider whitelistTableProvider - * @param string $moduleName - * @param array $whiteListTables - * @param array $expected - */ - public function testCommand($moduleName, array $whiteListTables, array $expected) - { - $commandTester = new CommandTester($this->model); - $options = !$moduleName ? [] : ['--module-name' => $moduleName]; - - if (!$moduleName) { - $this->componentRegistrarMock->expects(self::once()) - ->method('getPaths') - ->willReturn(['SomeModule' => 1, 'Module2' => 2]); - $this->readerCompositeMock->expects(self::exactly(3)) - ->method('read') - ->withConsecutive(['SomeModule'], ['primary'], ['Module2']) - ->willReturnOnConsecutiveCalls( - $whiteListTables['SomeModule'], - $whiteListTables['primary'], - $whiteListTables['Module2'] - ); - $this->jsonPersistorMock->expects(self::exactly(2)) - ->method('persist') - ->withConsecutive( - [ - $expected['SomeModule'], - '/etc/db_schema_whitelist.json' - ], - [ - $expected['Module2'], - '/etc/db_schema_whitelist.json' - ] - ); - } else { - $this->readerCompositeMock->expects(self::exactly(2)) - ->method('read') - ->withConsecutive([$moduleName], ['primary']) - ->willReturnOnConsecutiveCalls($whiteListTables['SomeModule'], $whiteListTables['primary']); - $this->jsonPersistorMock->expects(self::once()) - ->method('persist') - ->with( - $expected['SomeModule'], - '/etc/db_schema_whitelist.json' - ); - } - $commandTester->execute($options); - } -} diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Config/ConverterTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Config/ConverterTest.php index 2bb4bbcdb8d06..80b0517f7bfd3 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Config/ConverterTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Config/ConverterTest.php @@ -46,7 +46,7 @@ public function testConvert() - +
    @@ -74,12 +74,12 @@ public function testConvert() ], ], 'constraint' => [ - 'PRIMARY' => [ + 'PRIMARY_INDEX' => [ 'column' => [ 'id' => 'id', ], 'type' => 'primary', - 'name' => 'PRIMARY', + 'referenceId' => 'PRIMARY_INDEX', ], ], 'name' => 'test_table', diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php index 15dfcc746407e..88cf36eded3ed 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php @@ -299,9 +299,6 @@ public function testBuild(array $columns, array $references, array $constraints, * @param array $references * @param array $constraints * @param array $indexes - * @expectedException \Exception - * @expectedExceptionMessage - * User Warning: Column unknown_column does not exist for index/constraint FIRST_INDEX in table second_table */ public function testBuildUnknownIndexColumn(array $columns, array $references, array $constraints, array $indexes) { @@ -315,6 +312,11 @@ public function testBuildUnknownIndexColumn(array $columns, array $references, a Schema::class, ['resourceConnection' => $resourceConnectionMock] ); + $this->expectException(\PHPUnit\Framework\Exception::class); + $this->expectExceptionCode(E_USER_WARNING); + $this->expectExceptionMessage( + 'User Warning: Column unknown_column does not exist for index/constraint FIRST_INDEX in table second_table.' + ); $this->model->build($schema); } diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php deleted file mode 100644 index ee4331e7bfc5b..0000000000000 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php +++ /dev/null @@ -1,187 +0,0 @@ -objectManagerHelper = new ObjectManagerHelper($this); - $this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->resourceConnectionMock = $this->getMockBuilder(ResourceConnection::class) - ->disableOriginalConstructor() - ->getMock(); - $this->adapterMock = $this->getMockBuilder(AdapterInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->tableNameResolver = $this->getMockBuilder(TableNameResolver::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->foreignFactory = $this->objectManagerHelper->getObject( - Foreign::class, - [ - 'objectManager' => $this->objectManagerMock, - 'resourceConnection' => $this->resourceConnectionMock, - 'tableNameResolver' => $this->tableNameResolver, - ] - ); - } - - /** - * @param string $prefix - * @dataProvider createDataProvider - */ - public function testCreate(string $prefix) - { - $resource = 'default'; - $tableNameWithoutPrefix = 'table_name'; - $tableName = $prefix . $tableNameWithoutPrefix; - - $columnName = 'entity_id'; - $referenceTableName = 'second_table'; - $referenceColumnName = 'website_id'; - - $foreignKeyNameWithoutPrefix = 'table_name_field_name'; - $foreignKeyName = $prefix . $foreignKeyNameWithoutPrefix; - - $table = $this->objectManagerHelper->getObject( - DataObject::class, - [ - 'data' => [ - 'resource' => $resource, - 'name' => $tableName, - 'name_without_prefix' => $tableNameWithoutPrefix, - ], - ] - ); - - $columnMock = $this->objectManagerHelper->getObject( - DataObject::class, - [ - 'data' => ['name' => $columnName], - ] - ); - - $referenceTableMock = $this->objectManagerHelper->getObject( - DataObject::class, - [ - 'data' => ['name_without_prefix' => $referenceTableName], - ] - ); - - $referenceColumnMock = $this->objectManagerHelper->getObject( - DataObject::class, - [ - 'data' => ['name' => $referenceColumnName], - ] - ); - - $data = [ - 'name' => $foreignKeyName, - 'table' => $table, - 'column' => $columnMock, - 'referenceTable' => $referenceTableMock, - 'referenceColumn' => $referenceColumnMock, - ]; - - $expectedData = array_merge( - $data, - [ - 'onDelete' => Foreign::DEFAULT_ON_DELETE, - 'nameWithoutPrefix' => $foreignKeyNameWithoutPrefix, - ] - ); - - $this->resourceConnectionMock - ->method('getTablePrefix') - ->willReturn($prefix); - - $this->resourceConnectionMock - ->method('getConnection') - ->with($resource) - ->willReturn($this->adapterMock); - - $this->tableNameResolver - ->method('getNameOfOriginTable') - ->with($tableNameWithoutPrefix) - ->willReturn($tableNameWithoutPrefix); - - $this->adapterMock - ->method('getForeignKeyName') - ->with($tableNameWithoutPrefix, $columnName, $referenceTableName, $referenceColumnName) - ->willReturn($foreignKeyNameWithoutPrefix); - - $this->objectManagerMock - ->expects($this->once()) - ->method('create') - ->with(Reference::class, $expectedData); - - $this->foreignFactory->create($data); - } - - /** - * @return array - */ - public function createDataProvider(): array - { - return [ - 'Prefix is defined' => [ - 'pref_', - ], - 'Prefix is not defined' => [ - '', - ], - ]; - } -} From 9b99850eda727c39cd8ea074da673b84919ce026 Mon Sep 17 00:00:00 2001 From: Roman Ganin Date: Mon, 22 Oct 2018 14:08:24 -0500 Subject: [PATCH 432/812] MAGETWO-95595: Index names are ignored by declarative schema - test disable index --- .../Magento/TestSetupDeclarationModule1/etc/db_schema.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml index 30cb5b4d166ad..ae6c98e4627d2 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml @@ -65,8 +65,5 @@ - - - From 1c137111db27932fcfc5f7743f9996b2bd273904 Mon Sep 17 00:00:00 2001 From: Roman Ganin Date: Mon, 22 Oct 2018 14:28:44 -0500 Subject: [PATCH 433/812] MAGETWO-95654: Constraint removal is not treated as destructive operation --- app/code/Magento/AsynchronousOperations/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/AsynchronousOperations/composer.json b/app/code/Magento/AsynchronousOperations/composer.json index 18927b5f4ecca..7d5a097eeea3f 100644 --- a/app/code/Magento/AsynchronousOperations/composer.json +++ b/app/code/Magento/AsynchronousOperations/composer.json @@ -10,6 +10,7 @@ "magento/module-authorization": "*", "magento/module-backend": "*", "magento/module-ui": "*", + "magento/module-user": "*", "php": "~7.1.3||~7.2.0" }, "suggest": { From d6b614fc94c1f738700e76830f6bfde774582f08 Mon Sep 17 00:00:00 2001 From: Max Lesechko Date: Mon, 22 Oct 2018 14:53:43 -0500 Subject: [PATCH 434/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../TablesWhitelistGenerateCommand.php | 2 +- .../Declaration/Schema/WhitelistGenerator.php | 4 +-- .../Declaration/Schema/Config/Converter.php | 2 +- .../TableElement/ElementNameResolver.php | 32 +++++++++---------- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php index 9e1f9252c84b6..2155efa017093 100644 --- a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php +++ b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php @@ -79,7 +79,7 @@ protected function execute(InputInterface $input, OutputInterface $output) : int try { $this->whitelistGenerator->generate($moduleName); } catch (ConfigurationMismatchException $e) { - $output->writeln("". $e . ""); + $output->writeln($e->getMessage()); return \Magento\Framework\Console\Cli::RETURN_FAILURE; } catch (\Exception $e) { return \Magento\Framework\Console\Cli::RETURN_FAILURE; diff --git a/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php b/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php index b57abaf816f19..5cdcc6eb99af5 100644 --- a/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php +++ b/app/code/Magento/Developer/Model/Setup/Declaration/Schema/WhitelistGenerator.php @@ -161,7 +161,7 @@ private function persistModule(Schema $schema, string $moduleName) } /** - * Provides immutable names of the table elements. + * Provide immutable names of the table elements. * * @param array $tableData * @return array @@ -177,7 +177,7 @@ private function getElementsWithFixedName(array $tableData): array } /** - * Provides autogenerated names of the table elements. + * Provide autogenerated names of the table elements. * * @param Schema $schema * @param string $tableName diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php index 3882afb9f4360..149ad996a5fc4 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Config/Converter.php @@ -75,7 +75,7 @@ private function recursiveConvert(\Traversable $source): array } /** - * Provides the value of the ID attribute for each element. + * Provide the value of the ID attribute for each element. * * @param \DOMElement $element * @return string diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php index a3e66b9cf39c5..fe7d1a822dae1 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/TableElement/ElementNameResolver.php @@ -14,7 +14,7 @@ use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** - * Provides names of table elements with autogenerated names. + * Provide names of table elements with autogenerated names. */ class ElementNameResolver { @@ -39,7 +39,7 @@ public function __construct(TableNameResolver $tableNameResolver, ResourceConnec } /** - * Provides the full index name based on the prefix value. + * Provide the full index name based on the prefix value. * * @param Table $table * @param string[] $columns @@ -59,12 +59,11 @@ public function getFullIndexName( * Temporary solution. * @see MAGETWO-91365 */ - if ($type - && !array_search( - $type, - [AdapterInterface::INDEX_TYPE_FULLTEXT, AdapterInterface::INDEX_TYPE_UNIQUE] - ) - ) { + $isIndexTypeOutOfList = false === array_search( + $type, + [AdapterInterface::INDEX_TYPE_FULLTEXT, AdapterInterface::INDEX_TYPE_UNIQUE] + ); + if ($type && $isIndexTypeOutOfList) { $type = AdapterInterface::INDEX_TYPE_INDEX; } @@ -79,7 +78,7 @@ public function getFullIndexName( } /** - * Provides the index name without prefix value. + * Provide the index name without prefix value. * * @param string $name * @param Table $table @@ -104,12 +103,11 @@ public function getIndexNameWithoutPrefix( * Temporary solution. * @see MAGETWO-91365 */ - if ($type - && !array_search( - $type, - [AdapterInterface::INDEX_TYPE_FULLTEXT, AdapterInterface::INDEX_TYPE_UNIQUE] - ) - ) { + $isIndexTypeOutOfList = false === array_search( + $type, + [AdapterInterface::INDEX_TYPE_FULLTEXT, AdapterInterface::INDEX_TYPE_UNIQUE] + ); + if ($type && $isIndexTypeOutOfList) { $type = AdapterInterface::INDEX_TYPE_INDEX; } @@ -128,7 +126,7 @@ public function getIndexNameWithoutPrefix( } /** - * Provides the full foreign key name based on the prefix value. + * Provide the full foreign key name based on the prefix value. * * @param Table $table * @param Column $column @@ -154,7 +152,7 @@ public function getFullFKName( } /** - * Provides the foreign key name without prefix value. + * Provide the foreign key name without prefix value. * * @param string $name * @param Table $table From 1d65e1253bcc6b1f3f979414292a1f1803598a72 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko Date: Mon, 22 Oct 2018 15:30:43 -0500 Subject: [PATCH 435/812] MAGETWO-95501: Checkout page does not provide shipping methods option on cloud env - fix test --- .../Checkout/frontend/js/model/error-processor.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js index 3a6cd6d60d38b..772250eb7c66a 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/error-processor.test.js @@ -15,7 +15,8 @@ define([ 'mage/url': { /** Method stub. */ build: jasmine.createSpy() - } + }, + 'Magento_Ui/js/model/messageList': jasmine.createSpy('globalList') }, model; @@ -58,6 +59,7 @@ define([ it('check on failed status', function () { var messageContainer = jasmine.createSpyObj('globalMessageList', ['addErrorMessage']); + spyOn(window.location, 'replace').and.callFake(function () {}); model.process({ status: 401, responseText: '' From 1e9ea2e60bc5959a34347177c2654b34c2cbb443 Mon Sep 17 00:00:00 2001 From: Deepty Thampy Date: Mon, 22 Oct 2018 15:31:16 -0500 Subject: [PATCH 436/812] MAGETWO-95799: [Flaky test]Stabilize AdminAddImageToCMSPageTinyMCE3Test - removed commented out lines --- .../Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 9d3b498dc6ce6..11bf03c1d5ee9 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -22,13 +22,11 @@ - - From f39dec6732843170b0f43a34bf1ab58b7400093c Mon Sep 17 00:00:00 2001 From: Max Lesechko Date: Mon, 22 Oct 2018 16:06:07 -0500 Subject: [PATCH 437/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php index 88cf36eded3ed..4e0c129204012 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php @@ -312,8 +312,7 @@ public function testBuildUnknownIndexColumn(array $columns, array $references, a Schema::class, ['resourceConnection' => $resourceConnectionMock] ); - $this->expectException(\PHPUnit\Framework\Exception::class); - $this->expectExceptionCode(E_USER_WARNING); + $this->expectException(\Exception::class); $this->expectExceptionMessage( 'User Warning: Column unknown_column does not exist for index/constraint FIRST_INDEX in table second_table.' ); From ea6b86b3571890bcaa96ead4f059afebf3489712 Mon Sep 17 00:00:00 2001 From: Roman Ganin Date: Mon, 22 Oct 2018 16:23:37 -0500 Subject: [PATCH 438/812] MAGETWO-95654: Constraint removal is not treated as destructive operation --- app/code/Magento/AsynchronousOperations/etc/db_schema.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml index 95bd9bdcab283..342326e6666f1 100644 --- a/app/code/Magento/AsynchronousOperations/etc/db_schema.xml +++ b/app/code/Magento/AsynchronousOperations/etc/db_schema.xml @@ -27,8 +27,6 @@ - From 622a9a71f7af247a478b603eeab363dee99ac4c4 Mon Sep 17 00:00:00 2001 From: Roman Ganin Date: Mon, 22 Oct 2018 16:33:34 -0500 Subject: [PATCH 439/812] MAGETWO-95654: Constraint removal is not treated as destructive operation --- app/code/Magento/AsynchronousOperations/composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/AsynchronousOperations/composer.json b/app/code/Magento/AsynchronousOperations/composer.json index 7d5a097eeea3f..18927b5f4ecca 100644 --- a/app/code/Magento/AsynchronousOperations/composer.json +++ b/app/code/Magento/AsynchronousOperations/composer.json @@ -10,7 +10,6 @@ "magento/module-authorization": "*", "magento/module-backend": "*", "magento/module-ui": "*", - "magento/module-user": "*", "php": "~7.1.3||~7.2.0" }, "suggest": { From 3ed1819168cd16b995ddcd652d0aa2b3c07fde17 Mon Sep 17 00:00:00 2001 From: GwanYeong Kim Date: Tue, 23 Oct 2018 09:15:11 +0900 Subject: [PATCH 440/812] Remove Duplicate field --- dev/tests/js/jasmine/assets/gallery/config.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev/tests/js/jasmine/assets/gallery/config.json b/dev/tests/js/jasmine/assets/gallery/config.json index d1d8e94d7f220..72c36293bc152 100644 --- a/dev/tests/js/jasmine/assets/gallery/config.json +++ b/dev/tests/js/jasmine/assets/gallery/config.json @@ -59,8 +59,7 @@ "arrows": "false", "thumbwidth": "90", "thumbheight": "90", - "ratio": "1", - "allowfullscreen": true + "ratio": "1" }, "fullscreen": { "nav": false From 1d4b1610d6b2b6d72e591cef3f7c315b316e390f Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" Date: Tue, 23 Oct 2018 09:44:58 +0300 Subject: [PATCH 441/812] MAGETWO-94427: [2.3] Mini cart not getting updated if product disabled from backed --- .../Section/StorefrontMiniCartSection.xml | 16 ++ .../MarkQuotesRecollectMassDisabled.php | 55 +++++++ .../Quote/Model/Quote/TotalsCollector.php | 11 +- .../ResourceModel/Quote/Item/Collection.php | 143 ++++++++++++------ ...atusProductUsingProductGridActionGroup.xml | 33 ++++ .../Mftf/Section/AdminProductGridSection.xml | 14 ++ ...efrontGuestCheckoutDisabledProductTest.xml | 123 +++++++++++++++ app/code/Magento/Quote/etc/di.xml | 3 + 8 files changed, 350 insertions(+), 48 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMiniCartSection.xml create mode 100644 app/code/Magento/Quote/Model/Product/Plugin/MarkQuotesRecollectMassDisabled.php create mode 100644 app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml create mode 100644 app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml create mode 100644 app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMiniCartSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMiniCartSection.xml new file mode 100644 index 0000000000000..ff2e5f2f36015 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMiniCartSection.xml @@ -0,0 +1,16 @@ + + + + +
    + + + +
    +
    diff --git a/app/code/Magento/Quote/Model/Product/Plugin/MarkQuotesRecollectMassDisabled.php b/app/code/Magento/Quote/Model/Product/Plugin/MarkQuotesRecollectMassDisabled.php new file mode 100644 index 0000000000000..f18bb46fa63fb --- /dev/null +++ b/app/code/Magento/Quote/Model/Product/Plugin/MarkQuotesRecollectMassDisabled.php @@ -0,0 +1,55 @@ +quoteResource = $quoteResource; + } + + /** + * Clean quote items after mass disabling product + * + * @param \Magento\Catalog\Model\Product\Action $subject + * @param \Magento\Catalog\Model\Product\Action $result + * @param int[] $productIds + * @param int[] $attrData + * @param int $storeId + * @return \Magento\Catalog\Model\Product\Action + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterUpdateAttributes( + ProductAction $subject, + ProductAction $result, + $productIds, + $attrData, + $storeId + ): ProductAction { + if (isset($attrData['status']) && $attrData['status'] === Status::STATUS_DISABLED) { + $this->quoteResource->markQuotesRecollect($productIds); + } + + return $result; + } +} diff --git a/app/code/Magento/Quote/Model/Quote/TotalsCollector.php b/app/code/Magento/Quote/Model/Quote/TotalsCollector.php index 8fa03232a0e8d..9442cf2f5f1cb 100644 --- a/app/code/Magento/Quote/Model/Quote/TotalsCollector.php +++ b/app/code/Magento/Quote/Model/Quote/TotalsCollector.php @@ -103,6 +103,8 @@ public function __construct( } /** + * Collect quote totals. + * * @param \Magento\Quote\Model\Quote $quote * @return Address\Total */ @@ -115,6 +117,8 @@ public function collectQuoteTotals(\Magento\Quote\Model\Quote $quote) } /** + * Collect quote. + * * @param \Magento\Quote\Model\Quote $quote * @return \Magento\Quote\Model\Quote\Address\Total */ @@ -172,6 +176,8 @@ public function collect(\Magento\Quote\Model\Quote $quote) } /** + * Validate coupon code. + * * @param \Magento\Quote\Model\Quote $quote * @return $this */ @@ -203,11 +209,12 @@ protected function _validateCouponCode(\Magento\Quote\Model\Quote $quote) */ protected function _collectItemsQtys(\Magento\Quote\Model\Quote $quote) { + $quoteItems = $quote->getAllVisibleItems(); $quote->setItemsCount(0); $quote->setItemsQty(0); $quote->setVirtualItemsQty(0); - foreach ($quote->getAllVisibleItems() as $item) { + foreach ($quoteItems as $item) { if ($item->getParentItem()) { continue; } @@ -231,6 +238,8 @@ protected function _collectItemsQtys(\Magento\Quote\Model\Quote $quote) } /** + * Collect address total. + * * @param \Magento\Quote\Model\Quote $quote * @param Address $address * @return Address\Total diff --git a/app/code/Magento/Quote/Model/ResourceModel/Quote/Item/Collection.php b/app/code/Magento/Quote/Model/ResourceModel/Quote/Item/Collection.php index 4ca7d75af9e37..abecec395865d 100644 --- a/app/code/Magento/Quote/Model/ResourceModel/Quote/Item/Collection.php +++ b/app/code/Magento/Quote/Model/ResourceModel/Quote/Item/Collection.php @@ -3,9 +3,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Quote\Model\ResourceModel\Quote\Item; -use \Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; +use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\Quote\Item as QuoteItem; +use Magento\Quote\Model\ResourceModel\Quote\Item as ResourceQuoteItem; /** * Quote item resource collection @@ -50,6 +57,11 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\VersionContro */ private $storeManager; + /** + * @var bool $recollectQuote + */ + private $recollectQuote = false; + /** * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory * @param \Psr\Log\LoggerInterface $logger @@ -102,7 +114,7 @@ public function __construct( */ protected function _construct() { - $this->_init(\Magento\Quote\Model\Quote\Item::class, \Magento\Quote\Model\ResourceModel\Quote\Item::class); + $this->_init(QuoteItem::class, ResourceQuoteItem::class); } /** @@ -110,7 +122,7 @@ protected function _construct() * * @return int */ - public function getStoreId() + public function getStoreId(): int { // Fallback to current storeId if no quote is provided // (see https://github.com/magento/magento2/commit/9d3be732a88884a66d667b443b3dc1655ddd0721) @@ -119,12 +131,12 @@ public function getStoreId() } /** - * Set Quote object to Collection + * Set Quote object to Collection. * - * @param \Magento\Quote\Model\Quote $quote + * @param Quote $quote * @return $this */ - public function setQuote($quote) + public function setQuote($quote): self { $this->_quote = $quote; $quoteId = $quote->getId(); @@ -138,13 +150,15 @@ public function setQuote($quote) } /** - * Reset the collection and join it to quotes table. Optionally can select items with specified product id only. + * Reset the collection and inner join it to quotes table. + * + * Optionally can select items with specified product id only * * @param string $quotesTableName * @param int $productId * @return $this */ - public function resetJoinQuotes($quotesTableName, $productId = null) + public function resetJoinQuotes($quotesTableName, $productId = null): self { $this->getSelect()->reset()->from( ['qi' => $this->getResource()->getMainTable()], @@ -161,11 +175,11 @@ public function resetJoinQuotes($quotesTableName, $productId = null) } /** - * After load processing + * After load processing. * * @return $this */ - protected function _afterLoad() + protected function _afterLoad(): self { parent::_afterLoad(); @@ -194,11 +208,11 @@ protected function _afterLoad() } /** - * Add options to items + * Add options to items. * * @return $this */ - protected function _assignOptions() + protected function _assignOptions(): self { $itemIds = array_keys($this->_items); $optionCollection = $this->_itemOptionCollectionFactory->create()->addItemFilter($itemIds); @@ -212,12 +226,12 @@ protected function _assignOptions() } /** - * Add products to items and item options + * Add products to items and item options. * * @return $this * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - protected function _assignProducts() + protected function _assignProducts(): self { \Magento\Framework\Profiler::start('QUOTE:' . __METHOD__, ['group' => 'QUOTE', 'method' => __METHOD__]); $productCollection = $this->_productCollectionFactory->create()->setStoreId( @@ -239,46 +253,30 @@ protected function _assignProducts() ['collection' => $productCollection] ); - $recollectQuote = false; foreach ($this as $item) { + /** @var ProductInterface $product */ $product = $productCollection->getItemById($item->getProductId()); - if ($product) { + $isValidProduct = $this->isValidProduct($product); + $qtyOptions = []; + if ($isValidProduct) { $product->setCustomOptions([]); - $qtyOptions = []; - $optionProductIds = []; - foreach ($item->getOptions() as $option) { - /** - * Call type-specific logic for product associated with quote item - */ - $product->getTypeInstance()->assignProductToOption( - $productCollection->getItemById($option->getProductId()), - $option, - $product - ); - - if (is_object($option->getProduct()) && $option->getProduct()->getId() != $product->getId()) { - $optionProductIds[$option->getProduct()->getId()] = $option->getProduct()->getId(); - } - } - - if ($optionProductIds) { - foreach ($optionProductIds as $optionProductId) { - $qtyOption = $item->getOptionByCode('product_qty_' . $optionProductId); - if ($qtyOption) { - $qtyOptions[$optionProductId] = $qtyOption; - } + $optionProductIds = $this->getOptionProductIds($item, $product, $productCollection); + foreach ($optionProductIds as $optionProductId) { + $qtyOption = $item->getOptionByCode('product_qty_' . $optionProductId); + if ($qtyOption) { + $qtyOptions[$optionProductId] = $qtyOption; } } - - $item->setQtyOptions($qtyOptions)->setProduct($product); } else { $item->isDeleted(true); - $recollectQuote = true; + $this->recollectQuote = true; + } + if (!$item->isDeleted()) { + $item->setQtyOptions($qtyOptions)->setProduct($product); + $item->checkData(); } - $item->checkData(); } - - if ($recollectQuote && $this->_quote) { + if ($this->recollectQuote && $this->_quote) { $this->_quote->collectTotals(); } \Magento\Framework\Profiler::stop('QUOTE:' . __METHOD__); @@ -286,6 +284,57 @@ protected function _assignProducts() return $this; } + /** + * Get product Ids from option. + * + * @param QuoteItem $item + * @param ProductInterface $product + * @param ProductCollection $productCollection + * @return array + */ + private function getOptionProductIds( + QuoteItem $item, + ProductInterface $product, + ProductCollection $productCollection + ): array { + $optionProductIds = []; + foreach ($item->getOptions() as $option) { + /** + * Call type-specific logic for product associated with quote item + */ + $product->getTypeInstance()->assignProductToOption( + $productCollection->getItemById($option->getProductId()), + $option, + $product + ); + + if (is_object($option->getProduct()) && $option->getProduct()->getId() != $product->getId()) { + $isValidProduct = $this->isValidProduct($option->getProduct()); + if (!$isValidProduct && !$item->isDeleted()) { + $item->isDeleted(true); + $this->recollectQuote = true; + continue; + } + $optionProductIds[$option->getProduct()->getId()] = $option->getProduct()->getId(); + } + } + + return $optionProductIds; + } + + /** + * Check is valid product. + * + * @param ProductInterface $product + * @return bool + */ + private function isValidProduct(ProductInterface $product): bool + { + $result = ($product && (int)$product->getStatus() !== ProductStatus::STATUS_DISABLED); + + return $result; + } + /** * Prevents adding stock status filter to the collection of products. * @@ -294,7 +343,7 @@ protected function _assignProducts() * * @see \Magento\CatalogInventory\Helper\Stock::addIsInStockFilterToCollection */ - private function skipStockStatusFilter(ProductCollection $productCollection) + private function skipStockStatusFilter(ProductCollection $productCollection): void { $productCollection->setFlag('has_stock_status_filter', true); } @@ -304,7 +353,7 @@ private function skipStockStatusFilter(ProductCollection $productCollection) * * @return void */ - private function removeItemsWithAbsentProducts() + private function removeItemsWithAbsentProducts(): void { if (count($this->_productIds) === 0) { return; diff --git a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml new file mode 100644 index 0000000000000..dba4a94f3db2a --- /dev/null +++ b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml b/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml new file mode 100644 index 0000000000000..32ac73aca7c03 --- /dev/null +++ b/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml @@ -0,0 +1,14 @@ + + + + +
    + +
    +
    diff --git a/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml b/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml new file mode 100644 index 0000000000000..ab0db2dac643e --- /dev/null +++ b/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml @@ -0,0 +1,123 @@ + + + + + + + + + <description value="Remove item from cart if simple or configurable product is disabled"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-95857"/> + <group value="checkout"/> + </annotations> + <before> + <createData entity="SimpleSubCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!-- Create the configurable product based on the data in the /data folder --> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + + <!-- Make the configurable product have two options, that are children of the default attribute set --> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + + <!-- Create the 2 children that will be a part of the configurable product --> + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + + <!-- Assign the two products to the configurable product --> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + </before> + <after> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + </after> + <!-- Step 1: Add simple product to shopping cart --> + <amOnPage url="{{StorefrontProductPage.url($$createSimpleProduct.name$$)}}" stepKey="amOnSimpleProductPage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <actionGroup ref="AddSimpleProductToCart" stepKey="cartAddSimpleProductToCart"> + <argument name="product" value="$$createSimpleProduct$$"/> + <argument name="productCount" value="1"/> + </actionGroup> + <amOnPage url="{{StorefrontProductPage.url($$createConfigProduct.custom_attributes[url_key]$$)}}" stepKey="goToConfigProductPage"/> + <waitForPageLoad stepKey="waitForStoreFrontLoad"/> + <selectOption selector="{{StorefrontProductInfoMainSection.productAttributeOptionsSelectButton}}" userInput="$$getConfigAttributeOption1.value$$" stepKey="selectOption"/> + <click selector="{{StorefrontProductInfoMainSection.AddToCart}}" stepKey="clickAddToCart" /> + <waitForElement selector="{{StorefrontMessagesSection.messageProductAddedToCart($$createConfigProduct.name$$)}}" time="30" stepKey="assertMessage"/> + <!--Disabled via admin panel--> + <openNewTab stepKey="openNewTab"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!-- Find the first simple product that we just created using the product grid and go to its page--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPage"/> + <waitForPageLoad stepKey="waitForAdminProductGridLoad"/> + <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> + <actionGroup ref="filterProductGridBySku" stepKey="findCreatedProduct"> + <argument name="product" value="$$createConfigChildProduct1$$"/> + </actionGroup> + <waitForPageLoad stepKey="waitForFiltersToBeApplied"/> + <click selector="{{AdminProductGridSection.firstRow}}" stepKey="clickOnProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <!-- Disabled child configurable product --> + <click selector="{{AdminProductFormSection.enableProductAttributeLabel}}" stepKey="clickDisableProduct"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct"/> + <waitForPageLoad stepKey="waitForProductPageSaved"/> + <!-- Disabled simple product from grid --> + <actionGroup ref="ChangeStatusProductUsingProductGridActionGroup" stepKey="disabledProductFromGrid"> + <argument name="product" value="$$createSimpleProduct$$"/> + <argument name="status" value="Disable"/> + </actionGroup> + <closeTab stepKey="closeTab"/> + <!--Check cart--> + <reloadPage stepKey="reloadPage"/> + <waitForPageLoad stepKey="waitForCheckoutPageReload2"/> + <click selector="{{StorefrontMiniCartSection.show}}" stepKey="clickMiniCart"/> + <dontSeeElement selector="{{StorefrontMiniCartSection.quantity}}" stepKey="dontSeeCartItem"/> + </test> +</tests> diff --git a/app/code/Magento/Quote/etc/di.xml b/app/code/Magento/Quote/etc/di.xml index bc131b2987a8c..cd5e62307fdca 100644 --- a/app/code/Magento/Quote/etc/di.xml +++ b/app/code/Magento/Quote/etc/di.xml @@ -98,6 +98,9 @@ <plugin name="clean_quote_items_after_product_delete" type="Magento\Quote\Model\Product\Plugin\RemoveQuoteItems"/> <plugin name="update_quote_items_after_product_save" type="Magento\Quote\Model\Product\Plugin\UpdateQuoteItems"/> </type> + <type name="Magento\Catalog\Model\Product\Action"> + <plugin name="quoteProductMassChange" type="Magento\Quote\Model\Product\Plugin\MarkQuotesRecollectMassDisabled"/> + </type> <type name="Magento\Quote\Model\ValidationRules\QuoteValidationComposite"> <arguments> <argument name="validationRules" xsi:type="array"> From 937f5bcde4130966fc440df17a2a45e14717126d Mon Sep 17 00:00:00 2001 From: vgelani <vishalgelani99@gmail.com> Date: Tue, 23 Oct 2018 13:59:25 +0530 Subject: [PATCH 442/812] Replace intval() function by using direct type casting to (int) --- .../Quote/Api/CartTotalRepositoryTest.php | 30 +++++++++---------- .../Mtf/Util/Generate/Fixture/SchemaXml.php | 2 +- .../Constraint/AssertProductDuplicateForm.php | 2 +- .../Handler/CatalogProductSimple/Curl.php | 2 +- ...AssertConfigurableProductDuplicateForm.php | 2 +- .../Store/Test/Handler/StoreGroup/Curl.php | 2 +- .../Store/Test/Handler/Website/Curl.php | 2 +- .../Edit/Tab/View/PersonalInfoTest.php | 4 +-- pub/errors/processor.php | 2 +- .../Magento/Setup/Model/PhpReadinessCheck.php | 8 ++--- 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartTotalRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartTotalRepositoryTest.php index 609ae1cfe094c..a001cae645434 100644 --- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartTotalRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartTotalRepositoryTest.php @@ -162,22 +162,22 @@ protected function getQuoteItemTotalsData(\Magento\Quote\Model\Quote $quote) $item = array_shift($items); return [ ItemTotals::KEY_ITEM_ID => $item->getItemId(), - ItemTotals::KEY_PRICE => intval($item->getPrice()), - ItemTotals::KEY_BASE_PRICE => intval($item->getBasePrice()), + ItemTotals::KEY_PRICE => (int)$item->getPrice(), + ItemTotals::KEY_BASE_PRICE => (int)$item->getBasePrice(), ItemTotals::KEY_QTY => $item->getQty(), - ItemTotals::KEY_ROW_TOTAL => intval($item->getRowTotal()), - ItemTotals::KEY_BASE_ROW_TOTAL => intval($item->getBaseRowTotal()), - ItemTotals::KEY_ROW_TOTAL_WITH_DISCOUNT => intval($item->getRowTotalWithDiscount()), - ItemTotals::KEY_TAX_AMOUNT => intval($item->getTaxAmount()), - ItemTotals::KEY_BASE_TAX_AMOUNT => intval($item->getBaseTaxAmount()), - ItemTotals::KEY_TAX_PERCENT => intval($item->getTaxPercent()), - ItemTotals::KEY_DISCOUNT_AMOUNT => intval($item->getDiscountAmount()), - ItemTotals::KEY_BASE_DISCOUNT_AMOUNT => intval($item->getBaseDiscountAmount()), - ItemTotals::KEY_DISCOUNT_PERCENT => intval($item->getDiscountPercent()), - ItemTotals::KEY_PRICE_INCL_TAX => intval($item->getPriceInclTax()), - ItemTotals::KEY_BASE_PRICE_INCL_TAX => intval($item->getBasePriceInclTax()), - ItemTotals::KEY_ROW_TOTAL_INCL_TAX => intval($item->getRowTotalInclTax()), - ItemTotals::KEY_BASE_ROW_TOTAL_INCL_TAX => intval($item->getBaseRowTotalInclTax()), + ItemTotals::KEY_ROW_TOTAL => (int)$item->getRowTotal(), + ItemTotals::KEY_BASE_ROW_TOTAL => (int)$item->getBaseRowTotal(), + ItemTotals::KEY_ROW_TOTAL_WITH_DISCOUNT => (int)$item->getRowTotalWithDiscount(), + ItemTotals::KEY_TAX_AMOUNT => (int)$item->getTaxAmount(), + ItemTotals::KEY_BASE_TAX_AMOUNT => (int)$item->getBaseTaxAmount(), + ItemTotals::KEY_TAX_PERCENT => (int)$item->getTaxPercent(), + ItemTotals::KEY_DISCOUNT_AMOUNT => (int)$item->getDiscountAmount(), + ItemTotals::KEY_BASE_DISCOUNT_AMOUNT => (int)$item->getBaseDiscountAmount(), + ItemTotals::KEY_DISCOUNT_PERCENT => (int)$item->getDiscountPercent(), + ItemTotals::KEY_PRICE_INCL_TAX => (int)$item->getPriceInclTax(), + ItemTotals::KEY_BASE_PRICE_INCL_TAX => (int)$item->getBasePriceInclTax(), + ItemTotals::KEY_ROW_TOTAL_INCL_TAX => (int)$item->getRowTotalInclTax(), + ItemTotals::KEY_BASE_ROW_TOTAL_INCL_TAX => (int)$item->getBaseRowTotalInclTax(), ItemTotals::KEY_WEEE_TAX_APPLIED_AMOUNT => $item->getWeeeTaxAppliedAmount(), ItemTotals::KEY_WEEE_TAX_APPLIED => $item->getWeeeTaxApplied(), ItemTotals::KEY_NAME => $item->getName(), diff --git a/dev/tests/functional/lib/Magento/Mtf/Util/Generate/Fixture/SchemaXml.php b/dev/tests/functional/lib/Magento/Mtf/Util/Generate/Fixture/SchemaXml.php index aa85299deea44..6d1d5b6f4b349 100644 --- a/dev/tests/functional/lib/Magento/Mtf/Util/Generate/Fixture/SchemaXml.php +++ b/dev/tests/functional/lib/Magento/Mtf/Util/Generate/Fixture/SchemaXml.php @@ -145,7 +145,7 @@ protected function generateFixtureXml(array $config) foreach ($fields as $fieldName => $fieldValue) { $field = $this->dom->createElement('field'); $field->setAttribute('name', $fieldName); - $field->setAttribute('is_required', intval($fieldValue['is_required'])); + $field->setAttribute('is_required', (int)$fieldValue['is_required']); $fixture->appendChild($field); } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateForm.php index f65aa33ff93e3..d5cf5d918817d 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateForm.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductDuplicateForm.php @@ -116,7 +116,7 @@ function (&$item, $key, $formattingOptions) { protected function prepareUrlKey($urlKey) { preg_match("~\d+$~", $urlKey, $matches); - $key = intval($matches[0]) + 1; + $key = (int)$matches[0] + 1; return str_replace($matches[0], $key, $urlKey); } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php index c75112fee8605..2a23903a697b3 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php @@ -411,7 +411,7 @@ protected function prepareQuantityAndStockStatus() : ['is_in_stock' => 'In Stock']; if (!isset($quantityAndStockStatus['is_in_stock'])) { - $qty = isset($quantityAndStockStatus['qty']) ? intval($quantityAndStockStatus['qty']) : null; + $qty = isset($quantityAndStockStatus['qty']) ? (int)$quantityAndStockStatus['qty'] : null; $quantityAndStockStatus['is_in_stock'] = 0 === $qty ? 'Out of Stock' : 'In Stock'; } diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductDuplicateForm.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductDuplicateForm.php index 02cb304325c24..c50f0e338c20f 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductDuplicateForm.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductDuplicateForm.php @@ -70,7 +70,7 @@ protected function prepareFixtureData(array $data, array $sortFields = []) protected function prepareUrlKey($urlKey) { preg_match("~\d+$~", $urlKey, $matches); - $key = intval($matches[0]) + 1; + $key = (int)$matches[0] + 1; return str_replace($matches[0], $key, $urlKey); } diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php index 10ebd2b6d5f66..0c1017410961f 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/StoreGroup/Curl.php @@ -65,7 +65,7 @@ protected function getStoreGroupIdByGroupName($storeName) throw new \Exception('Cannot find store group id'); } - return intval($matches[1]); + return (int)$matches[1]; } /** diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php index ab0b1f2096808..0b738c5e159cd 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php @@ -119,7 +119,7 @@ protected function getWebSiteIdByWebsiteName($websiteName) throw new \Exception('Cannot find website id.'); } - return intval($matches[1]); + return (int)$matches[1]; } /** diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php index 8d82ad94dfab4..161734f47bfd7 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php @@ -110,9 +110,9 @@ public function testGetCustomer() \Magento\Customer\Api\Data\CustomerInterface::class ); foreach ($expectedCustomerData as $property => $value) { - $expectedValue = is_numeric($value) ? intval($value) : $value; + $expectedValue = is_numeric($value) ? (int)$value : $value; $actualValue = isset($actualCustomerData[$property]) ? $actualCustomerData[$property] : null; - $actualValue = is_numeric($actualValue) ? intval($actualValue) : $actualValue; + $actualValue = is_numeric($actualValue) ? (int)$actualValue : $actualValue; $this->assertEquals($expectedValue, $actualValue); } } diff --git a/pub/errors/processor.php b/pub/errors/processor.php index e64956dce17c2..ee8c9331097f7 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -466,7 +466,7 @@ protected function _setReportData($reportData) public function saveReport($reportData) { $this->reportData = $reportData; - $this->reportId = abs(intval(microtime(true) * random_int(100, 1000))); + $this->reportId = abs((int)(microtime(true) * random_int(100, 1000))); $this->_reportFile = $this->_reportDir . '/' . $this->reportId; $this->_setReportData($reportData); diff --git a/setup/src/Magento/Setup/Model/PhpReadinessCheck.php b/setup/src/Magento/Setup/Model/PhpReadinessCheck.php index 2c4967c4c2ffd..98da6cb7a5e0f 100644 --- a/setup/src/Magento/Setup/Model/PhpReadinessCheck.php +++ b/setup/src/Magento/Setup/Model/PhpReadinessCheck.php @@ -192,7 +192,7 @@ public function checkMemoryLimit() $currentMemoryLimit = ini_get('memory_limit'); - $currentMemoryInteger = intval($currentMemoryLimit); + $currentMemoryInteger = (int)$currentMemoryLimit; if ($currentMemoryInteger > 0 && $this->dataSize->convertSizeToBytes($currentMemoryLimit) @@ -244,7 +244,7 @@ private function checkXDebugNestedLevel() $currentExtensions = $this->phpInformation->getCurrent(); if (in_array('xdebug', $currentExtensions)) { - $currentXDebugNestingLevel = intval(ini_get('xdebug.max_nesting_level')); + $currentXDebugNestingLevel = (int)ini_get('xdebug.max_nesting_level'); $minimumRequiredXDebugNestedLevel = $this->phpInformation->getRequiredMinimumXDebugNestedLevel(); if ($minimumRequiredXDebugNestedLevel > $currentXDebugNestingLevel) { @@ -286,7 +286,7 @@ private function checkPopulateRawPostSetting() $data = []; $error = false; - $iniSetting = intval(ini_get('always_populate_raw_post_data')); + $iniSetting = (int)ini_get('always_populate_raw_post_data'); $checkVersionConstraint = $this->versionParser->parseConstraints('~5.6.0'); $normalizedPhpVersion = $this->getNormalizedCurrentPhpVersion(PHP_VERSION); @@ -302,7 +302,7 @@ private function checkPopulateRawPostSetting() Please open your php.ini file and set always_populate_raw_post_data to -1. If you need more help please call your hosting provider.', PHP_VERSION, - intval(ini_get('always_populate_raw_post_data')) + (int)ini_get('always_populate_raw_post_data') ); $data['always_populate_raw_post_data'] = [ From a9035918c120cba9dc139ad5240f78bc9c31ff29 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 23 Oct 2018 13:19:03 +0300 Subject: [PATCH 443/812] magento-engcom/magento2ce#2262: Code style fixes --- .../AdminNotification/Block/Window.php | 2 ++ .../Braintree/Controller/Paypal/Review.php | 5 +++- .../Magento/Framework/App/Config/Value.php | 8 +++--- .../Framework/App/Config/ValueInterface.php | 7 +++--- pub/errors/processor.php | 25 +++++++++++++------ 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/AdminNotification/Block/Window.php b/app/code/Magento/AdminNotification/Block/Window.php index 90a0a1d21d865..e9b4bfa44893d 100644 --- a/app/code/Magento/AdminNotification/Block/Window.php +++ b/app/code/Magento/AdminNotification/Block/Window.php @@ -8,6 +8,8 @@ namespace Magento\AdminNotification\Block; /** + * Admin notification window block + * * @api * @since 100.0.2 */ diff --git a/app/code/Magento/Braintree/Controller/Paypal/Review.php b/app/code/Magento/Braintree/Controller/Paypal/Review.php index e6a1dcbc34559..14ec829d98024 100644 --- a/app/code/Magento/Braintree/Controller/Paypal/Review.php +++ b/app/code/Magento/Braintree/Controller/Paypal/Review.php @@ -12,11 +12,12 @@ use Magento\Braintree\Gateway\Config\PayPal\Config; use Magento\Braintree\Model\Paypal\Helper\QuoteUpdater; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\App\Action\HttpPostActionInterface; /** * Class Review */ -class Review extends AbstractAction +class Review extends AbstractAction implements HttpPostActionInterface { /** * @var QuoteUpdater @@ -91,6 +92,8 @@ public function execute() } /** + * Validate request data + * * @param array $requestData * @return boolean */ diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index 7ba4225ce2fb8..9326fa4fa3f72 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -113,9 +113,9 @@ public function getFieldsetDataValue($key) } /** - * {@inheritdoc} + * @inheritdoc * - * {@inheritdoc}. In addition, it sets status 'invalidate' for config caches + * @inheritdoc. In addition, it sets status 'invalidate' for config caches * * @return $this */ @@ -129,9 +129,9 @@ public function afterSave() } /** - * {@inheritdoc} + * @inheritdoc * - * {@inheritdoc}. In addition, it sets status 'invalidate' for config caches + * @inheritdoc. In addition, it sets status 'invalidate' for config caches * * @return $this */ diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index 37e821f026869..6f2b6f37aca72 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -9,9 +9,9 @@ /** * Interface \Magento\Framework\App\Config\ValueInterface - * - * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going - * to introduce a new iterface which should cover all needs and deprecate the this one with the model + * + * This interface cannot be marked as API since doesn't fit developers' needs of extensibility. In 2.4 we are going + * to introduce a new interface which should cover all needs and deprecate the this one with the model * {@see \Magento\Framework\App\Config\Value} */ interface ValueInterface @@ -23,6 +23,7 @@ interface ValueInterface /** * Check if config data value was changed + * * @todo this method should be make as protected * @return bool */ diff --git a/pub/errors/processor.php b/pub/errors/processor.php index 2a7785f532f76..32fab8d0b0780 100644 --- a/pub/errors/processor.php +++ b/pub/errors/processor.php @@ -257,13 +257,7 @@ public function getHostUrl() /** * Define server http host */ - if (!empty($_SERVER['HTTP_HOST'])) { - $host = $_SERVER['HTTP_HOST']; - } elseif (!empty($_SERVER['SERVER_NAME'])) { - $host = $_SERVER['SERVER_NAME']; - } else { - $host = 'localhost'; - } + $host = $this->resolveHostName(); $isSecure = (!empty($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] !== 'off') || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'); @@ -278,6 +272,23 @@ public function getHostUrl() return $url; } + /** + * Resolve hostname + * + * @return string + */ + private function resolveHostName() : string + { + if (!empty($_SERVER['HTTP_HOST'])) { + $host = $_SERVER['HTTP_HOST']; + } elseif (!empty($_SERVER['SERVER_NAME'])) { + $host = $_SERVER['SERVER_NAME']; + } else { + $host = 'localhost'; + } + return $host; + } + /** * Retrieve base URL * From c3b3864118cccc1529e58e76bc25e5a3c42e6365 Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 23 Oct 2018 16:03:16 +0300 Subject: [PATCH 444/812] MAGETWO-90021: [Catalog] ProductAttributeMediaGalleryManagementInterface removes product from index, impossible to restore - Fix statics. --- .../Model/Product/Gallery/GalleryManagement.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php index 4be4bb09efc98..4a6cc09d11920 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -8,13 +7,15 @@ namespace Magento\Catalog\Model\Product\Gallery; use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface; -use Magento\Catalog\Api\Data\ProductInterface as Product; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; use Magento\Framework\Api\ImageContentValidatorInterface; /** + * Class GalleryManagement + * Provides implementation of api interface ProductAttributeMediaGalleryManagementInterface + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class GalleryManagement implements \Magento\Catalog\Api\ProductAttributeMediaGalleryManagementInterface @@ -44,7 +45,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function create($sku, ProductAttributeMediaGalleryEntryInterface $entry) { @@ -84,7 +85,7 @@ public function create($sku, ProductAttributeMediaGalleryEntryInterface $entry) } /** - * {@inheritdoc} + * @inheritdoc */ public function update($sku, ProductAttributeMediaGalleryEntryInterface $entry) { @@ -125,7 +126,7 @@ public function update($sku, ProductAttributeMediaGalleryEntryInterface $entry) } /** - * {@inheritdoc} + * @inheritdoc */ public function remove($sku, $entryId) { @@ -155,7 +156,7 @@ public function remove($sku, $entryId) } /** - * {@inheritdoc} + * @inheritdoc */ public function get($sku, $entryId) { @@ -176,7 +177,7 @@ public function get($sku, $entryId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getList($sku) { From c30ab0c9103860e29db5d1cac843d1d748bd8ebe Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 23 Oct 2018 17:05:28 +0300 Subject: [PATCH 445/812] MAGETWO-90021: [Catalog] ProductAttributeMediaGalleryManagementInterface removes product from index, impossible to restore - Fix statics. --- .../Magento/Catalog/Model/Product/Gallery/GalleryManagement.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php index 4a6cc09d11920..0e08b0af92862 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php @@ -14,6 +14,7 @@ /** * Class GalleryManagement + * * Provides implementation of api interface ProductAttributeMediaGalleryManagementInterface * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) From f66d26afbbe9e44afb800a6255213e11ae8fab72 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 23 Oct 2018 17:01:19 +0200 Subject: [PATCH 446/812] Added debug information for checking tests modules are deployed --- dev/tests/integration/framework/deployTestModules.php | 4 +++- dev/travis/before_script.sh | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/dev/tests/integration/framework/deployTestModules.php b/dev/tests/integration/framework/deployTestModules.php index 4c894d80f9800..f7be2b8414d23 100644 --- a/dev/tests/integration/framework/deployTestModules.php +++ b/dev/tests/integration/framework/deployTestModules.php @@ -1,4 +1,4 @@ -<?php +x<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. @@ -38,3 +38,5 @@ foreach ($files as $file) { include $file; } + +echo "\n\n TEST MODULES WERE DEPLOYED \n\n"; // DEBUG diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 52fd44c2826cc..c27e65d3897c7 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -152,9 +152,6 @@ case $TEST_SUITE in --admin-use-security-key=0 \ --admin-password="123123q" - php bin/magento module:status # DEBUG - php bin/magento setup:upgrade # DEBUG - echo "Enabling production mode" php bin/magento deploy:mode:set production From 2736ff910b56784ffe8513dec151d31b854dba65 Mon Sep 17 00:00:00 2001 From: pganapat <prabhuramgr28493@gmail.com> Date: Tue, 23 Oct 2018 10:11:20 -0500 Subject: [PATCH 447/812] MAGETWO-95213: Updating Product Status With Mass Action By Scope Updates The Default Value - Added MFTF case to cover the scenario MAGETWO-95213. Associated with Zephyr test MAGETWO-59361 --- .../ActionGroup/AdminProductActionGroup.xml | 21 +++ .../Catalog/Test/Mftf/Data/ProductData.xml | 30 ++++ .../Section/AdminProductFiltersSection.xml | 2 + .../Mftf/Section/AdminProductGridSection.xml | 1 + ...sUpdateProductStatusStoreViewScopeTest.xml | 151 ++++++++++++++++++ .../AdminFilterStoreViewActionGroup.xml | 21 +++ 6 files changed, 226 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml create mode 100644 app/code/Magento/Store/Test/Mftf/ActionGroup/AdminFilterStoreViewActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml index 9f8d827b20849..f06cc816e8595 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml @@ -277,4 +277,25 @@ <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> + <!--Create a Simple Product--> + <actionGroup name="createSimpleProductAndAddToWebsite"> + <arguments> + <argument name="product"/> + <argument name="website" type="string"/> + </arguments> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToCatalogProductGrid"/> + <waitForPageLoad stepKey="waitForProductGrid"/> + <click selector="{{AdminProductGridActionSection.addProductToggle}}" stepKey="clickAddProductDropdown"/> + <click selector="{{AdminProductGridActionSection.addSimpleProduct}}" stepKey="clickAddSimpleProduct"/> + <fillField userInput="{{product.name}}" selector="{{AdminProductFormSection.productName}}" stepKey="fillProductName"/> + <fillField userInput="{{product.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillProductSKU"/> + <fillField userInput="{{product.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillProductPrice"/> + <fillField userInput="{{product.quantity}}" selector="{{AdminProductFormSection.productQuantity}}" stepKey="fillProductQuantity"/> + <click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="openProductInWebsites"/> + <click selector="{{ProductInWebsitesSection.website(website)}}" stepKey="selectWebsite"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSave"/> + <waitForLoadingMaskToDisappear stepKey="waitForProductPageSave"/> + <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="seeSaveProductMessage"/> + </actionGroup> + </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index 7c0cc03186c6e..494335dd56f13 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -420,4 +420,34 @@ <data key="status">1</data> <requiredEntity type="product_extension_attribute">EavStock100</requiredEntity> </entity> + <entity name="simpleProductForMassUpdate" type="product"> + <data key="sku" unique="suffix">testSku</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">massUpdateProductName</data> + <data key="keyword">massUpdateProductName</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">masstesturlkey</data> + <data key="status">1</data> + <data key="quantity">100</data> + <data key="weight">1</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity> + </entity> + <entity name="simpleProductForMassUpdate2" type="product"> + <data key="sku" unique="suffix">testSku</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">massUpdateProductName</data> + <data key="keyword">massUpdateProductName</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">masstesturlkey</data> + <data key="status">1</data> + <data key="quantity">100</data> + <data key="weight">1</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity> + </entity> </entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml index 7a9de9670f216..06ff54b2a3997 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml @@ -28,5 +28,7 @@ <element name="priceOfFirstRow" type="text" selector="//tr[@data-repeat-index='0']//div[contains(., '{{var1}}')]" parameterized="true"/> <element name="AllProductsNotOfBundleType" type="text" selector="//td[5]/div[text() != 'Bundle Product']"/> <element name="attributeSetOfFirstRow" type="text" selector="//tr[@data-repeat-index='0']//div[contains(., '{{var1}}')]" parameterized="true"/> + <element name="storeViewDropDown" type="multiselect" selector="//select[@name='store_id']" timeout="30"/> + <element name="storeViewOption" type="multiselect" selector="//select[@name='store_id']/option[contains(text(),'{{var1}}')]" parameterized="true" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml index a7e20e22f1ddc..d12233206ce41 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductGridSection.xml @@ -28,6 +28,7 @@ <element name="firstRow" type="button" selector="tr.data-row:nth-of-type(1)"/> <element name="productGridCheckboxOnRow" type="checkbox" selector="//*[@id='container']//tr[{{row}}]/td[1]//input" parameterized="true"/> <element name="productGridNameProduct" type="input" selector="//tbody//tr//td//div[contains(., '{{var1}}')]" parameterized="true" timeout="30"/> + <element name="productGridContentsOnRow" type="checkbox" selector="//*[@id='container']//tr[{{row}}]/td" parameterized="true"/> <element name="selectRowBasedOnName" type="input" selector="//td/div[text()='{{var1}}']" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml new file mode 100644 index 0000000000000..6d1f266f4c66b --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml @@ -0,0 +1,151 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminMassUpdateProductStatusStoreViewScopeTest"> + <annotations> + <features value="Catalog"/> + <stories value="Mass update product status"/> + <title value="Admin should be able to mass update product statuses in store view scope"/> + <description value="Admin should be able to mass update product statuses in store view scope"/> + <severity value="AVERAGE"/> + <testCaseId value="MAGETWO-59361"/> + <group value="Catalog"/> + <group value="Product Attributes"/> + </annotations> + <before> + <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> + + <!--Create Website --> + <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createAdditionalWebsite"> + <argument name="newWebsiteName" value="Second Website"/> + <argument name="websiteCode" value="second_website"/> + </actionGroup> + + <!--Create Store --> + <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createNewStore"> + <argument name="website" value="Second Website"/> + <argument name="storeGroupName" value="Second Store"/> + <argument name="storeGroupCode" value="second_store"/> + </actionGroup> + + <!--Create Store view --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="amOnAdminSystemStorePage"/> + <waitForPageLoad stepKey="waitForSystemStorePage"/> + <click selector="{{AdminStoresMainActionsSection.createStoreViewButton}}" stepKey="createStoreViewButton"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <waitForElementVisible selector="//legend[contains(., 'Store View Information')]" stepKey="waitForNewStorePageToOpen"/> + <selectOption userInput="Second Store" selector="{{AdminNewStoreSection.storeGrpDropdown}}" stepKey="selectStoreGroup"/> + <fillField userInput="Second Store View" selector="{{AdminNewStoreSection.storeNameTextField}}" stepKey="fillStoreViewName"/> + <fillField userInput="second_store_view" selector="{{AdminNewStoreSection.storeCodeTextField}}" stepKey="fillStoreViewCode"/> + <selectOption selector="{{AdminNewStoreSection.statusDropdown}}" userInput="1" stepKey="enableStoreViewStatus"/> + <click selector="{{AdminNewStoreViewActionsSection.saveButton}}" stepKey="clickSaveStoreView" /> + <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> + <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> + <waitForPageLoad stepKey="waitForPageLoad2" time="180" /> + <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" time="150" stepKey="waitForPageReolad"/> + <see userInput="You saved the store view." stepKey="seeSavedMessage" /> + + <!--Create a Simple Product 1 --> + <actionGroup ref="createSimpleProductAndAddToWebsite" stepKey="createSimpleProduct1"> + <argument name="product" value="simpleProductForMassUpdate"/> + <argument name="website" value="Second Website"/> + </actionGroup> + + <!--Create a Simple Product 2 --> + <actionGroup ref="createSimpleProductAndAddToWebsite" stepKey="createSimpleProduct2"> + <argument name="product" value="simpleProductForMassUpdate2"/> + <argument name="website" value="Second Website"/> + </actionGroup> + </before> + <after> + <!--Delete website --> + <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteSecondWebsite"> + <argument name="websiteName" value="Second Website"/> + </actionGroup> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> + + <!--Delete Products --> + <actionGroup ref="DeleteProductActionGroup" stepKey="deleteProduct1"> + <argument name="productName" value="simpleProductForMassUpdate.name"/> + </actionGroup> + <actionGroup ref="DeleteProductActionGroup" stepKey="deleteProduct2"> + <argument name="productName" value="simpleProductForMassUpdate2.name"/> + </actionGroup> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + </after> + + <!-- Search and select products --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> + <waitForPageLoad stepKey="waitForProductIndexPageLoad"/> + <actionGroup ref="searchProductGridByKeyword2" stepKey="searchByKeyword"> + <argument name="keyword" value="{{simpleProductForMassUpdate.keyword}}"/> + </actionGroup> + <actionGroup ref="sortProductsByIdDescending" stepKey="sortProductsByIdDescending"/> + + <!-- Filter to Second Store View --> + <actionGroup ref="AdminFilterStoreViewActionGroup" stepKey="filterStoreView" > + <argument name="customStore" value="'Second Store View'" /> + </actionGroup> + + <!-- Select Product 2 --> + <click selector="{{AdminProductGridSection.productGridCheckboxOnRow('2')}}" stepKey="clickCheckbox2"/> + + <!-- Mass update attributes --> + <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickDropdown"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Change status')}}" stepKey="clickOption"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Disable')}}" stepKey="clickDisabled"/> + <waitForPageLoad stepKey="waitForBulkUpdatePage"/> + + <!-- Verify Product Statuses --> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('1')}}" userInput="Enabled" stepKey="checkIfProduct1IsEnabled"/> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('2')}}" userInput="Disabled" stepKey="checkIfProduct2IsDisabled"/> + + <!-- Filter to Default Store View --> + <actionGroup ref="AdminFilterStoreViewActionGroup" stepKey="filterDefaultStoreView"> + <argument name="customStore" value="'Default'" /> + </actionGroup> + + <!-- Verify Product Statuses --> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('1')}}" userInput="Enabled" stepKey="checkIfDefaultViewProduct1IsEnabled"/> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('2')}}" userInput="Enabled" stepKey="checkIfDefaultViewProduct2IsEnabled"/> + + <!-- Assert on storefront default view --> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupDefault"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameDefault"> + <argument name="name" value="{{simpleProductForMassUpdate.keyword}}"/> + <argument name="description" value=""/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault"/> + <see userInput="2 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInDefault"/> + + <!-- Enable the product in Default store view --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex2"/> + <waitForPageLoad stepKey="waitForProductIndexPageLoad2"/> + <click selector="{{AdminProductGridSection.productGridCheckboxOnRow('1')}}" stepKey="clickCheckboxDefaultStoreView"/> + <click selector="{{AdminProductGridSection.productGridCheckboxOnRow('2')}}" stepKey="clickCheckboxDefaultStoreView2"/> + + <!-- Mass update attributes --> + <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickDropdownDefaultStoreView"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Change status')}}" stepKey="clickOptionDefaultStoreView"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Disable')}}" stepKey="clickDisabledDefaultStoreView"/> + <waitForPageLoad stepKey="waitForBulkUpdatePageDefaultStoreView"/> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('1')}}" userInput="Disabled" stepKey="checkIfProduct2IsDisabledDefaultStoreView"/> + + <!-- Assert on storefront default view --> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupDefault2"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameDefault2"> + <argument name="name" value="{{simpleProductForMassUpdate.name}}"/> + <argument name="description" value=""/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault2"/> + <see userInput="We can't find any items matching these search criteria." selector="{{StorefrontCatalogSearchAdvancedResultMainSection.message}}" stepKey="seeInDefault2"/> + </test> +</tests> diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminFilterStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminFilterStoreViewActionGroup.xml new file mode 100644 index 0000000000000..e4cb26ea6ff7a --- /dev/null +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminFilterStoreViewActionGroup.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<!-- Test XML Example --> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminFilterStoreViewActionGroup"> + <arguments> + <argument name="StoreGroup" defaultValue="_defaultStoreGroup"/> + <argument name="customStore" defaultValue="customStore.name"/> + </arguments> + <click selector="{{AdminProductFiltersSection.filter}}" stepKey="ClickOnFilter"/> + <click selector="{{AdminProductFiltersSection.storeViewDropDown}}" stepKey="ClickOnStoreViewDropDown"/> + <click selector="{{AdminProductFiltersSection.storeViewOption(customStore)}}" stepKey="ClickOnStoreViewOption"/> + <click selector="{{AdminProductFiltersSection.applyFilters}}" stepKey="ClickOnApplyFilters"/> + </actionGroup> +</actionGroups> From 66329bbd41a6aac1d454c73c4e826e547dc81a02 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 23 Oct 2018 17:43:50 +0200 Subject: [PATCH 448/812] More details in debug information about deployed modules --- dev/tests/integration/framework/deployTestModules.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev/tests/integration/framework/deployTestModules.php b/dev/tests/integration/framework/deployTestModules.php index f7be2b8414d23..6e57d748a55eb 100644 --- a/dev/tests/integration/framework/deployTestModules.php +++ b/dev/tests/integration/framework/deployTestModules.php @@ -25,6 +25,7 @@ mkdir($targetDir, 0755, true); } copy($source, $destination); + echo "\n\nDestination $destination\n\n"; // DEBUG } } unset($iterator, $file); @@ -38,5 +39,3 @@ foreach ($files as $file) { include $file; } - -echo "\n\n TEST MODULES WERE DEPLOYED \n\n"; // DEBUG From 29cb28b41987ae4199fbc8ac14c3640d2224ec23 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 23 Oct 2018 17:58:54 +0200 Subject: [PATCH 449/812] Remove debug info --- dev/tests/integration/framework/deployTestModules.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/integration/framework/deployTestModules.php b/dev/tests/integration/framework/deployTestModules.php index 6e57d748a55eb..f4fb881d3ed70 100644 --- a/dev/tests/integration/framework/deployTestModules.php +++ b/dev/tests/integration/framework/deployTestModules.php @@ -25,7 +25,6 @@ mkdir($targetDir, 0755, true); } copy($source, $destination); - echo "\n\nDestination $destination\n\n"; // DEBUG } } unset($iterator, $file); From 4fdc63807fff721244e7ccff31064b634904075b Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 23 Oct 2018 18:04:52 +0200 Subject: [PATCH 450/812] removed accidentally added char --- dev/tests/integration/framework/deployTestModules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/framework/deployTestModules.php b/dev/tests/integration/framework/deployTestModules.php index f4fb881d3ed70..4c894d80f9800 100644 --- a/dev/tests/integration/framework/deployTestModules.php +++ b/dev/tests/integration/framework/deployTestModules.php @@ -1,4 +1,4 @@ -x<?php +<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. From cf6c3952630de4306384f49e0474e880d844cbec Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 23 Oct 2018 11:51:05 -0500 Subject: [PATCH 451/812] MAGETWO-95595: Index names are ignored by declarative schema --- .../Setup/Declaration/Schema/Operations/AddColumn.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php index 9a42090ad31db..71a1e2f92dfd8 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php @@ -110,7 +110,7 @@ private function getTemporaryIndexHistory(Column $column) Index::TYPE, [ 'name' => self::TEMPORARY_KEY, - 'column' => $column->getName(), + 'column' => [$column->getName()], 'columns' => [$column], 'table' => $column->getTable() ] @@ -119,7 +119,7 @@ private function getTemporaryIndexHistory(Column $column) } /** - * {@inheritdoc} + * @inheritdoc */ public function getOperationName() { @@ -127,7 +127,7 @@ public function getOperationName() } /** - * @return bool + * @inheritdoc */ public function isOperationDestructive() { @@ -187,7 +187,7 @@ private function setupTriggersIfExists(Statement $statement, ElementHistory $ele } /** - * {@inheritdoc} + * @inheritdoc */ public function doOperation(ElementHistory $elementHistory) { From a8c77686312a61ab151eb4c9a7a79a5f8127b3dd Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 13:46:53 -0500 Subject: [PATCH 452/812] Fix docblocks --- .../Timezone/LocalizedDateToUtcConverterInterface.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php index 277900c46badf..edc07bee164be 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php @@ -7,11 +7,16 @@ namespace Magento\Framework\Stdlib\DateTime\Timezone; +/* + * Interface for converting localized date to UTC + */ interface LocalizedDateToUtcConverterInterface { /** + * Convert localized date to UTC + * * @param string $data * @return string */ public function convertLocalizedDateToUtc($date); -} \ No newline at end of file +} From a18a08792acf1d251c491894d0889783d3b73c02 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Tue, 23 Oct 2018 22:48:01 +0300 Subject: [PATCH 453/812] graphQl-44: added html content resolver --- .../Resolver/Product/ProductTextAttribute.php | 64 ------------------- .../ProductTextAttribute/FormatInterface.php | 23 ------- .../ProductTextAttribute/FormatList.php | 54 ---------------- .../Product/ProductTextAttribute/Html.php | 47 -------------- .../ProductTextAttribute/HtmlContent.php | 56 ++++++++++++++++ .../CatalogGraphQl/etc/schema.graphqls | 29 ++------- 6 files changed, 61 insertions(+), 212 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php deleted file mode 100644 index 2ff6faa0a74ee..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Product; - -use Magento\Catalog\Model\Product; -use Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\FormatList; -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; - -/** - * Resolve rendered content for attributes where HTML content is allowed - */ -class ProductTextAttribute implements ResolverInterface -{ - /** - * @var FormatList - */ - private $formatList; - - /** - * @var string - */ - private $defaultFormat = 'html'; - - /** - * @param FormatList $formatList - */ - public function __construct( - FormatList $formatList - ) { - $this->formatList = $formatList; - } - - /** - * @inheritdoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ) { - if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); - } - - /* @var $product Product */ - $product = $value['model']; - $fieldName = $field->getName(); - $formatIdentifier = $args['filter']['description']['format'] ?? $this->defaultFormat; - $format = $this->formatList->getFormatByIdentifier($formatIdentifier); - $result = ['content' => $format->getContent($product, $fieldName)]; - - return $result; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.php deleted file mode 100644 index 2cf702bf18466..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatInterface.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\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; - -use Magento\Catalog\Model\Product as ModelProduct; - -interface FormatInterface -{ - /** - * @param ModelProduct $product - * @param string $fieldName - * @return string - */ - public function getContent( - ModelProduct $product, - string $fieldName - ): string; -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.php deleted file mode 100644 index 39f2074ed7592..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/FormatList.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\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; - -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\ObjectManagerInterface; - -/** - * Class FormatList - * @package Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute - */ -class FormatList -{ - /** - * @var ObjectManagerInterface - */ - private $objectManager; - - /** - * @var string - */ - private $formats; - - /** - * @param ObjectManagerInterface $objectManager - * @param array $formats - */ - public function __construct( - ObjectManagerInterface $objectManager, - array $formats - ) { - $this->objectManager = $objectManager; - $this->formats = $formats; - } - - /** - * @param string $formatIdentifier - * @return FormatInterface - */ - public function getFormatByIdentifier(string $formatIdentifier) : FormatInterface - { - if (!isset($this->formats[$formatIdentifier])) { - throw new GraphQlInputException(__('Format %1 does not exist.', [$formatIdentifier])); - } - $formatInstance = $this->objectManager->get($this->formats[$formatIdentifier]); - - return $formatInstance; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php deleted file mode 100644 index 830fbf28e3373..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/Html.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; - -use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; -use Magento\Catalog\Helper\Output as OutputHelper; -use Magento\Catalog\Model\Product as ModelProduct; - -class Html implements FormatInterface -{ - /** - * @var ValueFactory - */ - private $valueFactory; - - /** - * @var OutputHelper - */ - private $outputHelper; - - /** - * @param ValueFactory $valueFactory - * @param OutputHelper $outputHelper - */ - public function __construct( - ValueFactory $valueFactory, - OutputHelper $outputHelper - ) { - $this->valueFactory = $valueFactory; - $this->outputHelper = $outputHelper; - } - - /** - * @inheritdoc - */ - public function getContent( - ModelProduct $product, - string $fieldName - ): string { - return $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php new file mode 100644 index 0000000000000..c0b67889ecd74 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; + +use Magento\Catalog\Model\Product; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Catalog\Helper\Output as OutputHelper; + +/** + * HTML content of Product Text Attribute + */ +class HtmlContent implements ResolverInterface +{ + /** + * @var OutputHelper + */ + private $outputHelper; + + /** + * @param OutputHelper $outputHelper + */ + public function __construct( + OutputHelper $outputHelper + ) { + $this->outputHelper = $outputHelper; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ): array { + if (!isset($value['model'])) { + return []; + } + + /* @var $product Product */ + $product = $value['model']; + $fieldName = $field->getName(); + $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); + + return $renderedValue; + } +} diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index a7d9ab5483d46..3ffdc85a40d68 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") - short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -433,8 +433,8 @@ type CategoryProducts @doc(description: "The category products object returned i input ProductFilterInput @doc(description: "ProductFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") { name: FilterTypeInput @doc(description: "The product name. Customers use this name to identify the product.") sku: FilterTypeInput @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttributeTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: ProductTextAttributeTypeInput @doc(description: "A short description of the product. Its use depends on the theme.") + description: FilterTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.") + short_description: FilterTypeInput @doc(description: "A short description of the product. Its use depends on the theme.") price: FilterTypeInput @doc(description: "The price of an item") special_price: FilterTypeInput @doc(description: "The discounted price of the product") special_from_date: FilterTypeInput @doc(description: "The beginning date that a product has a special price") @@ -558,24 +558,5 @@ type SortFields @doc(description: "SortFields contains a default value for sort } type ProductTextAttribute @doc(description: "Product text attribute.") { - content: String -} - -input ProductTextAttributeTypeInput @doc(description: "FilterTypeInput specifies which action will be performed in a query ") { - format: String @doc(description: "Format of the content") - eq: String @doc(description: "Equals") - finset: [String] @doc(description: "Find in set. The value can contain a set of comma-separated values") - from: String @doc(description: "From. Must be used with 'to'") - gt: String @doc(description: "Greater than") - gteq: String @doc(description: "Greater than or equal to") - in: [String] @doc(description: "In. The value can contain a set of comma-separated values") - like: String @doc(description: "Like. The specified value can contain % (percent signs) to allow matching of 0 or more characters") - lt: String @doc(description: "Less than") - lteq: String @doc(description: "Less than or equal to") - moreq: String @doc(description: "More than or equal to") - neq: String @doc(description: "Not equal to") - notnull: String @doc(description: "Not null") - null: String @doc(description: "Is null") - to: String@doc(description: "To. Must be used with 'from'") - nin: [String] @doc(description: "Not in. The value can contain a set of comma-separated values") + html: String @doc(description: "Attribute HTML content") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute\\HtmlContent") } From 795bc1f0f449e1e599586bf42525d5c088cfbae2 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Tue, 23 Oct 2018 14:50:43 -0500 Subject: [PATCH 454/812] Merge remote-tracking branch 'upstream/2.3-develop' into 2.3.0-release-sync --- .../Model/Import/Product/CategoryProcessor.php | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php index f299fa010591e..951989146e67e 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php @@ -115,22 +115,14 @@ protected function createCategory($name, $parentId) if (!($parentCategory = $this->getCategoryById($parentId))) { $parentCategory = $this->categoryFactory->create()->load($parentId); } - - // Set StoreId to 0 to generate URL Keys global and prevent generating url rewrites just for default website - $category->setStoreId(0); $category->setPath($parentCategory->getPath()); $category->setParentId($parentId); $category->setName($this->unquoteDelimiter($name)); $category->setIsActive(true); $category->setIncludeInMenu(true); $category->setAttributeSetId($category->getDefaultAttributeSetId()); - try { - $category->save(); - $this->categoriesCache[$category->getId()] = $category; - } catch (\Exception $e) { - $this->addFailedCategory($category, $e); - } - + $category->save(); + $this->categoriesCache[$category->getId()] = $category; return $category->getId(); } From 127b1b8029a52fca7ad9726380f55c99c9db4c8a Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 15:28:11 -0500 Subject: [PATCH 455/812] Fix docblock --- app/code/Magento/Newsletter/Model/Queue.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Newsletter/Model/Queue.php b/app/code/Magento/Newsletter/Model/Queue.php index 58c5ba8a7e04a..a3279f8c83699 100644 --- a/app/code/Magento/Newsletter/Model/Queue.php +++ b/app/code/Magento/Newsletter/Model/Queue.php @@ -136,6 +136,7 @@ class Queue extends \Magento\Framework\Model\AbstractModel implements TemplateTy * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data * @param TimezoneInterface $timezone + * @param LocalizedDateToUtcConverterInterface $utcConverter * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( From 526bfc9267c837ef8b9bf7234869cf16d4327a26 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 15:31:08 -0500 Subject: [PATCH 456/812] Fix docblock --- lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 8534e798481cb..6514c01f92370 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -257,6 +257,8 @@ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) } /** + * Format date according to date and time formats, locale, timezone and pattern + * * @param string|\DateTimeInterface $date * @param int $dateType * @param int $timeType @@ -300,6 +302,7 @@ public function formatDateTime( /** * Convert date from config timezone to Utc. + * * If pass \DateTime object as argument be sure that timezone is the same with config timezone * * @param string|\DateTimeInterface $date From edc962dbf324a3866f9ac78537ce23abfc1316e4 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 15:32:37 -0500 Subject: [PATCH 457/812] Fix static tests --- .../DateTime/Timezone/LocalizedDateToUtcConverter.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php index 721ed9a384dad..420fd6e543e07 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverter.php @@ -36,13 +36,13 @@ class LocalizedDateToUtcConverter implements LocalizedDateToUtcConverterInterfac /** * LocalizedDateToUtcConverter constructor. * + * @param TimezoneInterface $timezone * @param ResolverInterface $localeResolver */ public function __construct( TimezoneInterface $timezone, ResolverInterface $localeResolver - ) - { + ) { $this->timezone = $timezone; $this->localeResolver = $localeResolver; } @@ -71,4 +71,4 @@ public function convertLocalizedDateToUtc($date) return $date->format($this->defaultFormat); } -} \ No newline at end of file +} From 4fe8c7a3ccc100d23f170dcef994477227aed35e Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 15:33:27 -0500 Subject: [PATCH 458/812] Fix static test --- .../DateTime/Timezone/LocalizedDateToUtcConverterInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php index edc07bee164be..d10bd5f2fefb2 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone/LocalizedDateToUtcConverterInterface.php @@ -15,7 +15,7 @@ interface LocalizedDateToUtcConverterInterface /** * Convert localized date to UTC * - * @param string $data + * @param string $date * @return string */ public function convertLocalizedDateToUtc($date); From e27de555edbbc24ff8a7037ee57de4deea306472 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 15:36:43 -0500 Subject: [PATCH 459/812] Fix static test --- .../Framework/Stdlib/DateTime/Timezone.php | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 6514c01f92370..cf747bfa2b735 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -257,15 +257,7 @@ public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null) } /** - * Format date according to date and time formats, locale, timezone and pattern - * - * @param string|\DateTimeInterface $date - * @param int $dateType - * @param int $timeType - * @param string|null $locale - * @param string|null $timezone - * @param string|null $pattern - * @return string + * @inheritdoc */ public function formatDateTime( $date, @@ -301,14 +293,7 @@ public function formatDateTime( } /** - * Convert date from config timezone to Utc. - * - * If pass \DateTime object as argument be sure that timezone is the same with config timezone - * - * @param string|\DateTimeInterface $date - * @param string $format - * @throws LocalizedException - * @return string + * @inheritdoc */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') { From 3cba00c951e0df4c843085ab761b9b97c2e3471b Mon Sep 17 00:00:00 2001 From: Tomash Khamlai <tomash.khamlai@gmail.com> Date: Tue, 23 Oct 2018 23:39:19 +0300 Subject: [PATCH 460/812] Cover \Magento\CheckoutAgreements\Model\ResourceModel\Agreement\Grid\Collection class with Integration test --- .../ResourceModel/Grid/CollectionTest.php | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php diff --git a/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php b/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php new file mode 100644 index 0000000000000..2f3112e705c94 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CheckoutAgreements\Model\ResourceModel\Grid; + +use Magento\CheckoutAgreements\Model\ResourceModel\Agreement\Grid\Collection; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Check data in collection + */ +class CollectionTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var Collection; + */ + private $collection; + + /** + * @inheritdoc + */ + public function setUp() + { + $this->collection = Bootstrap::getObjectManager()->create(Collection::class); + } + + /** + * Check that collection is filterable by store + * + * @magentoDataFixture Magento/CheckoutAgreements/_files/multi_agreements_active_with_text.php + */ + public function testAddStoresToFilter(): void + { + $collectionSize = $this->collection->addStoreFilter(1)->load(false, false)->getSize(); + $this->assertEquals(2, $collectionSize); + } +} From 0d0c210a7e081086a8235f9777a219601bd7e8c4 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 15:40:36 -0500 Subject: [PATCH 461/812] Fix static test --- .../Framework/Stdlib/DateTime/TimezoneInterface.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php index 4aff80161ef80..d1ac24c84be9a 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/TimezoneInterface.php @@ -6,6 +6,8 @@ namespace Magento\Framework\Stdlib\DateTime; +use Magento\Framework\Exception\LocalizedException; + /** * Timezone Interface * @api @@ -122,6 +124,8 @@ public function getConfigTimezone($scopeType = null, $scopeCode = null); public function isScopeDateInInterval($scope, $dateFrom = null, $dateTo = null); /** + * Format date according to date and time formats, locale, timezone and pattern. + * * @param string|\DateTimeInterface $date * @param int $dateType * @param int $timeType @@ -140,9 +144,14 @@ public function formatDateTime( ); /** + * Convert date from config timezone to UTC. + * + * If pass \DateTime object as argument be sure that timezone is the same with config timezone + * * @param string|\DateTimeInterface $date * @param string $format * @return string + * @throws LocalizedException * @since 100.1.0 */ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s'); From 29ccdae0897db8ef212b67a8ecf92e985c8d2e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Ca=C3=A7ador?= <20863811+samuel27m@users.noreply.github.com> Date: Tue, 23 Oct 2018 23:19:31 +0100 Subject: [PATCH 462/812] Remove unnecesary "header" block redeclaration Remove unnecesary header block redeclaration on Magento Luma Theme, which made impossible to set the header template through custom modules. Example: - Create new module. - Create new default.xml and try to use referenceBlock to set the template. - Doesn't work, because Luma theme XML files are compiled after all modules and overrides the custom module modifications. Removed because this block was already created in module Magento_Theme, so this redeclaration is just unnecesary --- .../Magento/luma/Magento_Customer/layout/default.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Customer/layout/default.xml b/app/design/frontend/Magento/luma/Magento_Customer/layout/default.xml index 1f8c162ef923a..4b08bf28ece9f 100644 --- a/app/design/frontend/Magento/luma/Magento_Customer/layout/default.xml +++ b/app/design/frontend/Magento/luma/Magento_Customer/layout/default.xml @@ -15,11 +15,6 @@ </arguments> </block> </referenceBlock> - <block class="Magento\Theme\Block\Html\Header" name="header" as="header"> - <arguments> - <argument name="show_part" xsi:type="string">welcome</argument> - </arguments> - </block> <move element="header" destination="header.links" before="-"/> <move element="register-link" destination="header.links"/> <move element="top.links" destination="customer"/> From 6e1710aec76825c8fc03e1e159f518dfba8d18e4 Mon Sep 17 00:00:00 2001 From: pganapat <prabhuramgr28493@gmail.com> Date: Tue, 23 Oct 2018 17:29:09 -0500 Subject: [PATCH 463/812] MAGETWO-95213: Updating Product Status With Mass Action By Scope Updates The Default Value - Review comments fix. Using action group for logout. --- .../Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml index 6d1f266f4c66b..e9b54e3f1a3dc 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml @@ -79,7 +79,7 @@ <actionGroup ref="DeleteProductActionGroup" stepKey="deleteProduct2"> <argument name="productName" value="simpleProductForMassUpdate2.name"/> </actionGroup> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="amOnLogoutPage"/> </after> <!-- Search and select products --> From 7b078de306f1c48eaf16544df53516b4c4d412a2 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 23 Oct 2018 17:55:35 -0500 Subject: [PATCH 464/812] ENGCOM-3214: Add Value, ReadFactory and WriteFactory to Magento Framework's public API --- .../Magento/Test/Legacy/_files/obsolete_constants.php | 1 - lib/internal/Magento/Framework/App/Config/Value.php | 10 +++++----- .../Magento/Framework/App/Config/ValueInterface.php | 2 ++ 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php index cbf499c8dad38..5bcc712be6f74 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php @@ -712,7 +712,6 @@ 'Magento\Sales\Block\Reorder\Sidebar', '\Magento\Sales\CustomerData\LastOrderedItems::SIDEBAR_ORDER_LIMIT', ], - ['ENTITY', 'Magento\Framework\App\Config\ValueInterface'], ['XML_PATH_ALLOW_CURRENCIES_INSTALLED', 'Magento\Framework\Locale\CurrencyInterface'], [ 'DEFAULT_CURRENCY', diff --git a/lib/internal/Magento/Framework/App/Config/Value.php b/lib/internal/Magento/Framework/App/Config/Value.php index 9326fa4fa3f72..6fde4dded4695 100644 --- a/lib/internal/Magento/Framework/App/Config/Value.php +++ b/lib/internal/Magento/Framework/App/Config/Value.php @@ -9,7 +9,7 @@ * Config data model * * This model is temporarily marked as API since {@see \Magento\Framework\App\Config\ValueInterface} doesn't fit - * developers' needs of extensibility. In 2.4 we are going to introduce a new iterface which should cover all needs + * developers' needs of extensibility. In 2.4 we are going to introduce a new interface which should cover all needs * and deprecate the mentioned together with the model * * @method string getScope() @@ -113,9 +113,9 @@ public function getFieldsetDataValue($key) } /** - * @inheritdoc + * Processing object after save data * - * @inheritdoc. In addition, it sets status 'invalidate' for config caches + * {@inheritdoc}. In addition, it sets status 'invalidate' for config caches * * @return $this */ @@ -129,9 +129,9 @@ public function afterSave() } /** - * @inheritdoc + * Processing object after delete data * - * @inheritdoc. In addition, it sets status 'invalidate' for config caches + * {@inheritdoc}. In addition, it sets status 'invalidate' for config caches * * @return $this */ diff --git a/lib/internal/Magento/Framework/App/Config/ValueInterface.php b/lib/internal/Magento/Framework/App/Config/ValueInterface.php index 6f2b6f37aca72..0aa600b84dcce 100644 --- a/lib/internal/Magento/Framework/App/Config/ValueInterface.php +++ b/lib/internal/Magento/Framework/App/Config/ValueInterface.php @@ -18,6 +18,8 @@ interface ValueInterface { /** * Table name + * + * @deprecated since it is not used */ const ENTITY = 'config_data'; From 0dc76a43811ac8598abc4530cab1fe976aa734a2 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 24 Oct 2018 08:44:12 +0300 Subject: [PATCH 465/812] ENGCOM-17516: added Australian states --- .../Setup/Patch/Data/AddDataForAustralia.php | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php new file mode 100644 index 0000000000000..7574f684bb465 --- /dev/null +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Directory\Setup\Patch\Data; + +use Magento\Directory\Setup\DataInstaller; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Framework\Setup\Patch\DataPatchInterface; +use Magento\Framework\Setup\Patch\PatchVersionInterface; + +/** + * Adds Australian States + */ +class AddDataForAustralia implements DataPatchInterface, PatchVersionInterface +{ + /** + * @var ModuleDataSetupInterface + */ + private $moduleDataSetup; + + /** + * @var \Magento\Directory\Setup\DataInstallerFactory + */ + private $dataInstallerFactory; + + /** + * AddDataForCroatia constructor. + * + * @param ModuleDataSetupInterface $moduleDataSetup + * @param \Magento\Directory\Setup\DataInstallerFactory $dataInstallerFactory + */ + public function __construct( + ModuleDataSetupInterface $moduleDataSetup, + \Magento\Directory\Setup\DataInstallerFactory $dataInstallerFactory + ) { + $this->moduleDataSetup = $moduleDataSetup; + $this->dataInstallerFactory = $dataInstallerFactory; + } + + /** + * {@inheritdoc} + */ + public function apply() + { + /** @var DataInstaller $dataInstaller */ + $dataInstaller = $this->dataInstallerFactory->create(); + $dataInstaller->addCountryRegions( + $this->moduleDataSetup->getConnection(), + $this->getDataForAustralia() + ); + } + + /** + * Croatian states data. + * + * @return array + */ + private function getDataForAustralia() + { + return [ + ['AU', 'ACT', 'Australian Capital Territory'], + ['AU', 'NSW', 'New South Wales'], + ['AU', 'VIC', 'Victoria'], + ['AU', 'QLD', 'Queensland'], + ['AU', 'SA', 'South Australia'], + ['AU', 'TAS', 'Tasmania'], + ['AU', 'WA', 'Western Australia'], + ['AU', 'NT', 'Northern Territory'] + ]; + } + + /** + * {@inheritdoc} + */ + public static function getDependencies() + { + return [ + InitializeDirectoryData::class, + ]; + } + + /** + * {@inheritdoc} + */ + public static function getVersion() + { + return '2.0.3'; + } + + /** + * {@inheritdoc} + */ + public function getAliases() + { + return []; + } +} From 50ff962c0d838cfd58a2c151bbb86730f23f00c8 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 24 Oct 2018 08:51:12 +0300 Subject: [PATCH 466/812] ENGCOM-17516: Fixed phpdocs --- .../Directory/Setup/Patch/Data/AddDataForAustralia.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php index 7574f684bb465..0abadf7153424 100644 --- a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php @@ -27,8 +27,6 @@ class AddDataForAustralia implements DataPatchInterface, PatchVersionInterface private $dataInstallerFactory; /** - * AddDataForCroatia constructor. - * * @param ModuleDataSetupInterface $moduleDataSetup * @param \Magento\Directory\Setup\DataInstallerFactory $dataInstallerFactory */ @@ -54,7 +52,7 @@ public function apply() } /** - * Croatian states data. + * Australian states data. * * @return array */ From e7d5aa8c8bb959b3d03c5d8f75ce3eee4727df00 Mon Sep 17 00:00:00 2001 From: Sergey Shvets <sshvets@magento.com> Date: Tue, 23 Oct 2018 17:04:32 +0300 Subject: [PATCH 467/812] MAGETWO-95848: Customer Cart Checkout error --- .../Item/ItemProductResolver.php | 56 ++++--- .../Item/ItemProductResolverTest.php | 143 ++++++++++++++++++ 2 files changed, 176 insertions(+), 23 deletions(-) create mode 100644 app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Configuration/Item/ItemProductResolverTest.php diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Configuration/Item/ItemProductResolver.php b/app/code/Magento/ConfigurableProduct/Model/Product/Configuration/Item/ItemProductResolver.php index 6c33ecc138aea..7de78b6612a10 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Configuration/Item/ItemProductResolver.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Configuration/Item/ItemProductResolver.php @@ -13,16 +13,17 @@ use Magento\Catalog\Model\Product\Configuration\Item\ItemResolverInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Catalog\Model\Product; +use Magento\Store\Model\ScopeInterface; /** - * {@inheritdoc} + * Resolves the product from a configured item. */ class ItemProductResolver implements ItemResolverInterface { /** * Path in config to the setting which defines if parent or child product should be used to generate a thumbnail. */ - const CONFIG_THUMBNAIL_SOURCE = 'checkout/cart/configurable_product_image'; + public const CONFIG_THUMBNAIL_SOURCE = 'checkout/cart/configurable_product_image'; /** * @var ScopeConfigInterface @@ -38,27 +39,21 @@ public function __construct(ScopeConfigInterface $scopeConfig) } /** - * {@inheritdoc} + * Get the final product from a configured item by product type and selection. + * + * @param ItemInterface $item + * @return ProductInterface */ - public function getFinalProduct(ItemInterface $item) : ProductInterface + public function getFinalProduct(ItemInterface $item): ProductInterface { /** * Show parent product thumbnail if it must be always shown according to the related setting in system config * or if child thumbnail is not available. */ - $parentProduct = $item->getProduct(); - $finalProduct = $parentProduct; + $finalProduct = $item->getProduct(); $childProduct = $this->getChildProduct($item); - if ($childProduct !== $parentProduct) { - $configValue = $this->scopeConfig->getValue( - self::CONFIG_THUMBNAIL_SOURCE, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ); - $childThumb = $childProduct->getData('thumbnail'); - $finalProduct = - ($configValue == Thumbnail::OPTION_USE_PARENT_IMAGE) || (!$childThumb || $childThumb == 'no_selection') - ? $parentProduct - : $childProduct; + if ($childProduct !== null && $this->isUseChildProduct($childProduct)) { + $finalProduct = $childProduct; } return $finalProduct; } @@ -67,15 +62,30 @@ public function getFinalProduct(ItemInterface $item) : ProductInterface * Get item configurable child product. * * @param ItemInterface $item - * @return Product + * @return Product | null */ - private function getChildProduct(ItemInterface $item) : Product + private function getChildProduct(ItemInterface $item): ?Product { + /** @var \Magento\Quote\Model\Quote\Item\Option $option */ $option = $item->getOptionByCode('simple_product'); - $product = $item->getProduct(); - if ($option) { - $product = $option->getProduct(); - } - return $product; + return $option ? $option->getProduct() : null; + } + + /** + * Is need to use child product + * + * @param Product $childProduct + * @return bool + */ + private function isUseChildProduct(Product $childProduct): bool + { + $configValue = $this->scopeConfig->getValue( + self::CONFIG_THUMBNAIL_SOURCE, + ScopeInterface::SCOPE_STORE + ); + $childThumb = $childProduct->getData('thumbnail'); + return $configValue !== Thumbnail::OPTION_USE_PARENT_IMAGE + && $childThumb !== null + && $childThumb !== 'no_selection'; } } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Configuration/Item/ItemProductResolverTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Configuration/Item/ItemProductResolverTest.php new file mode 100644 index 0000000000000..8dac2dee10d37 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Configuration/Item/ItemProductResolverTest.php @@ -0,0 +1,143 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\ConfigurableProduct\Test\Unit\Model\Product\Configuration\Item; + +use Magento\Catalog\Model\Config\Source\Product\Thumbnail; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface; +use Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface; +use Magento\ConfigurableProduct\Model\Product\Configuration\Item\ItemProductResolver; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Quote\Model\Quote\Item\Option; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +class ItemProductResolverTest extends TestCase +{ + /** @var ItemProductResolver */ + private $model; + /** @var ItemInterface | MockObject */ + private $item; + /** @var Product | MockObject */ + private $parentProduct; + /** @var ScopeConfigInterface | MockObject */ + private $scopeConfig; + /** @var OptionInterface | MockObject */ + private $option; + /** @var Product | MockObject */ + private $childProduct; + + /** + * Set up method + */ + protected function setUp() + { + parent::setUp(); + + $this->scopeConfig = $this->getMockBuilder(ScopeConfigInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->parentProduct = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->getMock(); + $this->parentProduct + ->method('getSku') + ->willReturn('parent_product'); + + $this->childProduct = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->getMock(); + $this->childProduct + ->method('getSku') + ->willReturn('child_product'); + + $this->option = $this->getMockBuilder(Option::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->option + ->method('getProduct') + ->willReturn($this->childProduct); + + $this->item = $this->getMockBuilder(ItemInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->item + ->expects($this->once()) + ->method('getProduct') + ->willReturn($this->parentProduct); + + $this->model = new ItemProductResolver($this->scopeConfig); + } + + /** + * Test for deleted child product from configurable product + */ + public function testGetFinalProductChildIsNull(): void + { + $this->scopeConfig->expects($this->never())->method('getValue'); + $this->childProduct->expects($this->never())->method('getData'); + + $this->item->expects($this->once()) + ->method('getOptionByCode') + ->willReturn(null); + + $finalProduct = $this->model->getFinalProduct($this->item); + $this->assertEquals( + $this->parentProduct->getSku(), + $finalProduct->getSku() + ); + } + + /** + * Tests child product from configurable product + * + * @dataProvider provideScopeConfig + * @param string $expectedSku + * @param string $scopeValue + * @param string | null $thumbnail + */ + public function testGetFinalProductChild($expectedSku, $scopeValue, $thumbnail): void + { + $this->item->expects($this->once()) + ->method('getOptionByCode') + ->willReturn($this->option); + + $this->childProduct + ->expects($this->once()) + ->method('getData') + ->willReturn($thumbnail); + + $this->scopeConfig->expects($this->once()) + ->method('getValue') + ->willReturn($scopeValue); + + $finalProduct = $this->model->getFinalProduct($this->item); + $this->assertEquals($expectedSku, $finalProduct->getSku()); + } + + /** + * Dataprovider for scope test + * @return array + */ + public function provideScopeConfig(): array + { + return [ + ['child_product', Thumbnail::OPTION_USE_OWN_IMAGE, 'thumbnail'], + ['parent_product', Thumbnail::OPTION_USE_PARENT_IMAGE, 'thumbnail'], + + ['parent_product', Thumbnail::OPTION_USE_OWN_IMAGE, null], + ['parent_product', Thumbnail::OPTION_USE_OWN_IMAGE, 'no_selection'], + + ['parent_product', Thumbnail::OPTION_USE_PARENT_IMAGE, null], + ['parent_product', Thumbnail::OPTION_USE_PARENT_IMAGE, 'no_selection'], + ]; + } +} From d9de494dcfd714101117a6619895805aeec6f8e8 Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Wed, 24 Oct 2018 01:24:02 -0700 Subject: [PATCH 468/812] MAGETWO-95520: Verify that Catalog Price Rule and Customer Group Membership are persisted under long-term cookie --- .../CatalogPriceRuleActionGroup.xml | 19 +++++ ...hipArePersistedUnderLongTermCookieTest.xml | 85 +++++++++++++++++++ .../Section/StorefrontPanelHeaderSection.xml | 1 + .../Test/Mftf/Data/PersistentData.xml | 14 +++ .../Mftf/Metadata/persistent_config-meta.xml | 3 + 5 files changed, 122 insertions(+) create mode 100644 app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml index cfd41f2ab970c..fe4042e8a2e9f 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml @@ -58,4 +58,23 @@ <fillField selector="{{AdminNewCatalogPriceRuleConditions.targetInput('1', '1')}}" userInput="{{productSku}}" after="clickEllipsis" stepKey="fillProductSku"/> <click selector="{{AdminNewCatalogPriceRuleConditions.applyButton('1', '1')}}" after="fillProductSku" stepKey="clickApply"/> </actionGroup> + + <!--Add Catalog Rule Condition With Category--> + <actionGroup name="newCatalogPriceRuleByUIWithConditionIsCategory" extends="newCatalogPriceRuleByUI"> + <arguments> + <argument name="categoryId"/> + </arguments> + <click selector="{{AdminNewCatalogPriceRule.conditionsTab}}" after="discardSubsequentRules" stepKey="openConditionsTab"/> + <waitForPageLoad after="openConditionsTab" stepKey="waitForConditionTabOpened"/> + <click selector="{{AdminNewCatalogPriceRuleConditions.newCondition}}" after="waitForConditionTabOpened" stepKey="addNewCondition"/> + <selectOption selector="{{AdminNewCatalogPriceRuleConditions.conditionSelect('1')}}" userInput="Magento\CatalogRule\Model\Rule\Condition\Product|category_ids" after="addNewCondition" stepKey="selectTypeCondition"/> + <waitForPageLoad after="selectTypeCondition" stepKey="waitForConditionChosed"/> + <click selector="{{AdminNewCatalogPriceRuleConditions.targetEllipsis('1')}}" after="waitForConditionChosed" stepKey="clickEllipsis"/> + <fillField selector="{{AdminNewCatalogPriceRuleConditions.targetInput('1', '1')}}" userInput="{{categoryId}}" after="clickEllipsis" stepKey="fillCategoryId"/> + <click selector="{{AdminNewCatalogPriceRuleConditions.applyButton('1', '1')}}" after="fillCategoryId" stepKey="clickApply"/> + </actionGroup> + + <actionGroup name="selectGeneralCustomerGroupActionGroup"> + <selectOption selector="{{AdminNewCatalogPriceRule.customerGroups}}" userInput="General" stepKey="selectCustomerGroup"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml new file mode 100644 index 0000000000000..2e09ee7134733 --- /dev/null +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest.xml @@ -0,0 +1,85 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CatalogPriceRuleAndCustomerGroupMembershipArePersistedUnderLongTermCookieTest"> + <annotations> + <features value="Persistent"/> + <stories value="Check the price"/> + <title value="Verify that Catalog Price Rule and Customer Group Membership are persisted under long-term cookie"/> + <description value="Verify that Catalog Price Rule and Customer Group Membership are persisted under long-term cookie"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-69455"/> + <group value="persistent"/> + </annotations> + <before> + <createData entity="PersistentConfigEnabled" stepKey="enablePersistent"/> + <createData entity="PersistentLogoutClearDisable" stepKey="persistentLogoutClearDisable"/> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + <field key="price">50</field> + </createData> + <createData entity="Simple_US_Customer" stepKey="createCustomer"> + <field key="group_id">1</field> + </createData> + + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + <!--Create Catalog Rule--> + <actionGroup ref="newCatalogPriceRuleByUIWithConditionIsCategory" stepKey="createCatalogPriceRule"> + <argument name="catalogRule" value="_defaultCatalogRule"/> + <argument name="categoryId" value="$$createCategory.id$$"/> + </actionGroup> + <actionGroup ref="selectGeneralCustomerGroupActionGroup" stepKey="selectCustomerGroup"/> + <click selector="{{AdminNewCatalogPriceRule.saveAndApply}}" stepKey="clickSaveAndApplyRules"/> + <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the rule." stepKey="assertSuccess"/> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <!-- Delete the rule --> + <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToCatalogPriceRulePage"/> + <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deletePriceRule"> + <argument name="name" value="{{_defaultCatalogRule.name}}"/> + <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> + </actionGroup> + <actionGroup ref="logout" stepKey="logout"/> + <createData entity="PersistentConfigDefault" stepKey="setDefaultPersistentState"/> + <createData entity="PersistentLogoutClearEnabled" stepKey="persistentLogoutClearEnabled"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + </after> + + <!--Go to category and check price--> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onStorefrontCategoryPage"/> + <see selector="{{StorefrontCategoryProductSection.ProductPriceByNumber('1')}}" userInput="$$createProduct.price$$" stepKey="checkPriceSimpleProduct"/> + + <!--Login to storfront from customer and check price--> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="logInFromCustomer"> + <argument name="Customer" value="$$createCustomer$$"/> + </actionGroup> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onStorefrontCategoryPage2"/> + <see userInput="Welcome, $$createCustomer.firstname$$ $$createCustomer.lastname$$!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeCheckWelcome"/> + <see selector="{{StorefrontCategoryProductSection.ProductSpecialPriceByNumber('1')}}" userInput="45.00" stepKey="checkPriceSimpleProduct2"/> + + <!--Click *Sign Out* and check the price of the Simple Product--> + <actionGroup ref="StorefrontSignOutActionGroup" stepKey="storefrontSignOut"/> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onStorefrontCategoryPage3"/> + <see userInput="Welcome, $$createCustomer.firstname$$ $$createCustomer.lastname$$!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeCheckWelcome2"/> + <seeElement selector="{{StorefrontPanelHeaderSection.notYouLink}}" stepKey="checkLinkNotYoy"/> + <see selector="{{StorefrontCategoryProductSection.ProductSpecialPriceByNumber('1')}}" userInput="45.00" stepKey="checkPriceSimpleProduct3"/> + + <!--Click the *Not you?* link and check the price for Simple Product--> + <click selector="{{StorefrontPanelHeaderSection.notYouLink}}" stepKey="clickNext"/> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onStorefrontCategoryPage4"/> + <see userInput="Default welcome msg!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeCheckWelcome3"/> + <see selector="{{StorefrontCategoryProductSection.ProductPriceByNumber('1')}}" userInput="$$createProduct.price$$" stepKey="checkPriceSimpleProduct4"/> + </test> +</tests> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml index 06b82db767ab5..a0c83f5bc491b 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml @@ -11,5 +11,6 @@ <section name="StorefrontPanelHeaderSection"> <element name="WelcomeMessage" type="text" selector=".greet.welcome span"/> <element name="createAnAccountLink" type="select" selector=".panel.header li:nth-child(3)" timeout="30"/> + <element name="notYouLink" type="button" selector=".greet.welcome span a"/> </section> </sections> diff --git a/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml b/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml index f4e2fa198e7ff..3d42ae6da81a5 100644 --- a/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml +++ b/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml @@ -20,4 +20,18 @@ <entity name="persistentEnabledState" type="persistent_options_enabled"> <data key="value">1</data> </entity> + + <entity name="PersistentLogoutClearEnabled" type="persistent_config_state"> + <requiredEntity type="persistent_options_logout_clear">persistentEnabledLogoutClear</requiredEntity> + </entity> + <entity name="persistentEnabledLogoutClear" type="logout_clear"> + <data key="value">1</data> + </entity> + + <entity name="PersistentLogoutClearDisable" type="persistent_config_state"> + <requiredEntity type="persistent_options_logout_clear">persistentDisableLogoutClear</requiredEntity> + </entity> + <entity name="persistentDisableLogoutClear" type="logout_clear"> + <data key="value">0</data> + </entity> </entities> diff --git a/app/code/Magento/Persistent/Test/Mftf/Metadata/persistent_config-meta.xml b/app/code/Magento/Persistent/Test/Mftf/Metadata/persistent_config-meta.xml index d165ca5f929b0..7f0e12f8bef93 100644 --- a/app/code/Magento/Persistent/Test/Mftf/Metadata/persistent_config-meta.xml +++ b/app/code/Magento/Persistent/Test/Mftf/Metadata/persistent_config-meta.xml @@ -14,6 +14,9 @@ <object key="enabled" dataType="persistent_options_enabled"> <field key="value">string</field> </object> + <object key="logout_clear" dataType="persistent_options_logout_clear"> + <field key="value">string</field> + </object> </object> </object> </object> From 0a4dc35bb14a28634a7b58e9fe12e68df7e86ea7 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 24 Oct 2018 14:21:40 +0300 Subject: [PATCH 469/812] graphQl-44: added ProductTextAttribute and fixed api functional test --- .../Resolver/Product/ProductTextAttribute.php | 33 +++++++++++++++++ .../ProductTextAttribute/HtmlContent.php | 10 ++++-- .../CatalogGraphQl/etc/schema.graphqls | 4 +-- .../GraphQl/Catalog/ProductViewTest.php | 36 ++++++++++++++++--- 4 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php new file mode 100644 index 0000000000000..171e84a65aba4 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -0,0 +1,33 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; + +/** + * Resolve rendered content for text attributes + */ +class ProductTextAttribute implements ResolverInterface +{ + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ): array { + $value['field'] = $field->getName(); + + return $value; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php index c0b67889ecd74..724d0826dbb3d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php @@ -9,6 +9,7 @@ use Magento\Catalog\Model\Product; use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Helper\Output as OutputHelper; @@ -41,14 +42,17 @@ public function resolve( ResolveInfo $info, array $value = null, array $args = null - ): array { + ): ?string { if (!isset($value['model'])) { - return []; + throw new GraphQlInputException(__('"model" value should be specified')); + } + if (!isset($value['field'])) { + throw new GraphQlInputException(__('"field" value should be specified')); } /* @var $product Product */ $product = $value['model']; - $fieldName = $field->getName(); + $fieldName = $value['field']; $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); return $renderedValue; diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 3ffdc85a40d68..ad724c18a5c9a 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") - short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") + description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") 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 7c2cda3a4551b..615e50f640380 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -44,7 +44,9 @@ public function testQueryAllFieldsSimpleProduct() attribute_set_id country_of_manufacture created_at - description + description { + html + } gift_message_available id categories { @@ -203,7 +205,9 @@ public function testQueryAllFieldsSimpleProduct() position sku } - short_description + short_description { + html + } sku small_image { path @@ -262,6 +266,7 @@ public function testQueryAllFieldsSimpleProduct() $this->assertArrayHasKey(0, $response['products']['items']); $this->assertBaseFields($product, $response['products']['items'][0]); $this->assertEavAttributes($product, $response['products']['items'][0]); + $this->assertTextEavAttributes($product, $response['products']['items'][0]); $this->assertOptions($product, $response['products']['items'][0]); $this->assertTierPrices($product, $response['products']['items'][0]); $this->assertArrayHasKey('websites', $response['products']['items'][0]); @@ -917,11 +922,9 @@ private function assertEavAttributes($product, $actualResponse) { $eavAttributes = [ 'url_key', - 'description', 'meta_description', 'meta_keyword', 'meta_title', - 'short_description', 'country_of_manufacture', 'gift_message_available', 'news_from_date', @@ -943,6 +946,31 @@ private function assertEavAttributes($product, $actualResponse) $this->assertResponseFields($actualResponse, $assertionMap); } + /** + * @param ProductInterface $product + * @param array $actualResponse + */ + private function assertTextEavAttributes($product, $actualResponse) + { + $eavAttributes = [ + 'description', + 'short_description', + ]; + $assertionMap = []; + foreach ($eavAttributes as $attributeCode) { + $expectedAttribute = $product->getCustomAttribute($attributeCode); + + $assertionMap[] = [ + 'response_field' => $this->eavAttributesToGraphQlSchemaFieldTranslator($attributeCode), + 'expected_value' => $expectedAttribute ? [ + 'html' => $expectedAttribute->getValue() + ] : null + ]; + } + + $this->assertResponseFields($actualResponse, $assertionMap); + } + /** * @param string $eavAttributeCode * @return string From 5fe9697ceec3d0192b9be5125c2cfb5f301521ba Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Wed, 24 Oct 2018 05:40:18 -0700 Subject: [PATCH 470/812] MAGETWO-95520: Verify that Catalog Price Rule and Customer Group Membership are persisted under long-term cookie --- .../Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index 73025023c23c8..45c6c90a76973 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -25,7 +25,6 @@ <argument name="ProductAttribute" type="string"/> </arguments> <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> <fillField selector="{{AdminProductAttributeGridSection.GridFilterFrontEndLabel}}" userInput="{{ProductAttribute}}" stepKey="navigateToAttributeEditPage1" /> <click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="navigateToAttributeEditPage2" /> <waitForPageLoad stepKey="waitForPageLoad2" /> From 6862c04ece31c29d41be7ac65005e9bdf7c24490 Mon Sep 17 00:00:00 2001 From: Sunil Patel <patelsunil42@gmail.com> Date: Sat, 19 May 2018 15:50:34 +0530 Subject: [PATCH 471/812] 15259 : Unable to disable without providing Industry value --- app/code/Magento/Analytics/etc/adminhtml/system.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Analytics/etc/adminhtml/system.xml b/app/code/Magento/Analytics/etc/adminhtml/system.xml index 4e21648d00ce8..c7da840b7e665 100644 --- a/app/code/Magento/Analytics/etc/adminhtml/system.xml +++ b/app/code/Magento/Analytics/etc/adminhtml/system.xml @@ -36,6 +36,9 @@ <source_model>Magento\Analytics\Model\Config\Source\Vertical</source_model> <backend_model>Magento\Analytics\Model\Config\Backend\Vertical</backend_model> <frontend_model>Magento\Analytics\Block\Adminhtml\System\Config\Vertical</frontend_model> + <depends> + <field id="analytics/general/enabled">1</field> + </depends> </field> <field id="additional_comment" translate="label comment" type="label" sortOrder="40" showInDefault="1" showInWebsite="0" showInStore="0"> <label><![CDATA[<strong>Get more insights from Magento Business Intelligence</strong>]]></label> From 857908e3ef1b06ef66cfa9c2910861e90eb6bcfd Mon Sep 17 00:00:00 2001 From: Stas Puga <stas.puga@transoftgroup.com> Date: Wed, 24 Oct 2018 16:37:54 +0300 Subject: [PATCH 472/812] MAGETWO-95517: Add different types of products on the quote including gift card --- .../Section/StorefrontProductInfoMainSection.xml | 1 + .../Mftf/Data/ProductAttributeOptionData.xml | 16 ++++++++++++++++ .../Catalog/Test/Mftf/Data/StoreLabelData.xml | 16 ++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontProductInfoMainSection.xml b/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontProductInfoMainSection.xml index 735571375866e..fae1ec331b667 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontProductInfoMainSection.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Section/StorefrontProductInfoMainSection.xml @@ -13,5 +13,6 @@ <element name="priceTo" type="text" selector=".product-info-price .price-to"/> <element name="minPrice" type="text" selector="span[data-price-type='minPrice']"/> <element name="maxPrice" type="text" selector="span[data-price-type='minPrice']"/> + <element name="productBundleOptionsCheckbox" type="checkbox" selector="//*[@id='product-options-wrapper']//div[@class='fieldset']//label[contains(.,'{{childName}}')]/../input" parameterized="true" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml index c575f1a5db82f..c21f23d16463e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml @@ -65,4 +65,20 @@ <data key="is_default">false</data> <data key="sort_order">0</data> </entity> + <entity name="productAttributeOption7" type="ProductAttributeOption"> + <var key="attribute_code" entityKey="attribute_code" entityType="ProductAttribute"/> + <data key="label" unique="suffix">Green</data> + <data key="is_default">false</data> + <data key="sort_order">3</data> + <requiredEntity type="StoreLabel">Option7Store0</requiredEntity> + <requiredEntity type="StoreLabel">Option8Store1</requiredEntity> + </entity> + <entity name="productAttributeOption8" type="ProductAttributeOption"> + <var key="attribute_code" entityKey="attribute_code" entityType="ProductAttribute"/> + <data key="label" unique="suffix">Red</data> + <data key="is_default">false</data> + <data key="sort_order">3</data> + <requiredEntity type="StoreLabel">Option9Store0</requiredEntity> + <requiredEntity type="StoreLabel">Option10Store1</requiredEntity> + </entity> </entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/StoreLabelData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/StoreLabelData.xml index ce964e2d71503..0e51995ac72e8 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/StoreLabelData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/StoreLabelData.xml @@ -56,4 +56,20 @@ <data key="store_id">1</data> <data key="label">option6</data> </entity> + <entity name="Option7Store0" type="StoreLabel"> + <data key="store_id">0</data> + <data key="label">Green</data> + </entity> + <entity name="Option8Store1" type="StoreLabel"> + <data key="store_id">1</data> + <data key="label">Green</data> + </entity> + <entity name="Option9Store0" type="StoreLabel"> + <data key="store_id">0</data> + <data key="label">Red</data> + </entity> + <entity name="Option10Store1" type="StoreLabel"> + <data key="store_id">1</data> + <data key="label">Red</data> + </entity> </entities> From 5ef522d0b2178c0d8086df04cdb4c282200ce7fa Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Wed, 24 Oct 2018 10:46:13 -0500 Subject: [PATCH 473/812] MQE-1304: MFTF test failures between 5pm PDT and midnight PDT --- .../Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml | 2 ++ .../Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml | 2 ++ .../Mftf/Test/CartPriceRuleForConfigurableProductTest.xml | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml index aaedaedb7236c..ace50aa3e6d33 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml @@ -50,6 +50,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{ApiSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsite"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="chooseNotLoggedInCustomerGroup"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> <fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="{{_defaultCoupon.code}}" stepKey="fillCouponCode"/> <fillField selector="{{AdminCartPriceRulesFormSection.userPerCoupon}}" userInput="99" stepKey="fillUserPerCoupon"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml index 60df3f27fd65b..08e859b11d1bb 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml @@ -45,6 +45,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{ApiSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsite"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="chooseNotLoggedInCustomerGroup"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <!-- Open the Actions Tab in the Rules Edit page --> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml index 4c194c63ec378..e2687f5f16baf 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml @@ -7,7 +7,7 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="CartPriceRuleForConfigurableProductTest"> <annotations> <features value="SalesRule"/> @@ -96,6 +96,8 @@ <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="yesterdayDate"/> + <fillField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="{$yesterdayDate}" stepKey="fillFromDate"/> <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> <fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="ABCD" stepKey="fillCouponCOde"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> From 88197c8b1624f9dc82dbea3fc0a5cbc3986f259d Mon Sep 17 00:00:00 2001 From: Pratik Oza <pratik.oza@krishtechnolabs.com> Date: Wed, 24 Oct 2018 22:22:56 +0530 Subject: [PATCH 474/812] Remove useless semicolon statements --- .../catalog/product/attribute/set/main/tree/attribute.phtml | 2 +- .../CatalogSearch/Model/Indexer/Fulltext/Action/Full.php | 2 +- app/code/Magento/GiftMessage/Model/ItemRepository.php | 4 ++-- app/code/Magento/GiftMessage/Model/OrderItemRepository.php | 4 ++-- app/code/Magento/GiftMessage/Model/OrderRepository.php | 2 +- .../Magento/Indexer/Console/Command/IndexerReindexCommand.php | 2 +- app/code/Magento/Indexer/Model/DimensionModes.php | 2 +- app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php | 2 +- .../view/adminhtml/templates/importExportHeader.phtml | 2 +- app/code/Magento/Theme/Model/Design/Config/Validator.php | 2 +- app/code/Magento/Theme/view/frontend/templates/text.phtml | 2 +- .../Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php | 4 ++-- .../Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.php | 2 +- .../app/Magento/ImportExport/Test/Fixture/Import/File.php | 2 +- .../integration/testsuite/Magento/Deploy/_files/theme.php | 2 +- .../GiftMessage/_files/quote_with_item_message_rollback.php | 2 +- .../Test/Integrity/Magento/Backend/ControllerAclTest.php | 2 +- .../Framework/Indexer/Config/DependencyInfoProvider.php | 2 +- lib/internal/Magento/Framework/Setup/OldDbValidator.php | 2 +- .../Unit/Autoloader/GeneratedClassesAutoloader.php | 2 +- 20 files changed, 23 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main/tree/attribute.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main/tree/attribute.phtml index 223b3e9888eea..75f04eae82159 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main/tree/attribute.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main/tree/attribute.phtml @@ -2,4 +2,4 @@ /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. - */; + */ diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php index 2b4be8369de59..7c93595b2b9ff 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php @@ -400,7 +400,7 @@ public function rebuildStoreIndex($storeId, $productIds = null) } $products = $this->dataProvider ->getSearchableProducts($storeId, $staticFields, $productIds, $lastProductId, $this->batchSize); - }; + } } /** diff --git a/app/code/Magento/GiftMessage/Model/ItemRepository.php b/app/code/Magento/GiftMessage/Model/ItemRepository.php index 3c62a489af4ab..dce60079e43e3 100644 --- a/app/code/Magento/GiftMessage/Model/ItemRepository.php +++ b/app/code/Magento/GiftMessage/Model/ItemRepository.php @@ -88,7 +88,7 @@ public function get($cartId, $itemId) throw new NoSuchEntityException( __('No item with the provided ID was found in the Cart. Verify the ID and try again.') ); - }; + } $messageId = $item->getGiftMessageId(); if (!$messageId) { return null; @@ -121,7 +121,7 @@ public function save($cartId, \Magento\GiftMessage\Api\Data\MessageInterface $gi $itemId ) ); - }; + } if ($item->getIsVirtual()) { throw new InvalidTransitionException(__('Gift messages can\'t be used for virtual products.')); diff --git a/app/code/Magento/GiftMessage/Model/OrderItemRepository.php b/app/code/Magento/GiftMessage/Model/OrderItemRepository.php index 943552e2b75bc..6cfcd485f7645 100644 --- a/app/code/Magento/GiftMessage/Model/OrderItemRepository.php +++ b/app/code/Magento/GiftMessage/Model/OrderItemRepository.php @@ -89,7 +89,7 @@ public function get($orderId, $orderItemId) throw new NoSuchEntityException( __('No item with the provided ID was found in the Order. Verify the ID and try again.') ); - }; + } if (!$this->helper->isMessagesAllowed('order_item', $orderItem, $this->storeManager->getStore())) { throw new NoSuchEntityException( @@ -123,7 +123,7 @@ public function save($orderId, $orderItemId, \Magento\GiftMessage\Api\Data\Messa throw new NoSuchEntityException( __('No item with the provided ID was found in the Order. Verify the ID and try again.') ); - }; + } if ($order->getIsVirtual()) { throw new InvalidTransitionException(__("Gift messages can't be used for virtual products.")); diff --git a/app/code/Magento/GiftMessage/Model/OrderRepository.php b/app/code/Magento/GiftMessage/Model/OrderRepository.php index abf38f1287b7a..88d1adf92ed0b 100644 --- a/app/code/Magento/GiftMessage/Model/OrderRepository.php +++ b/app/code/Magento/GiftMessage/Model/OrderRepository.php @@ -106,7 +106,7 @@ public function save($orderId, \Magento\GiftMessage\Api\Data\MessageInterface $g $order = $this->orderFactory->create()->load($orderId); if (!$order->getEntityId()) { throw new NoSuchEntityException(__('No order exists with this ID. Verify your information and try again.')); - }; + } if (0 == $order->getTotalItemCount()) { throw new InputException( diff --git a/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php b/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php index 6eab92f65117a..6d0716a6f1c27 100644 --- a/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php +++ b/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php @@ -187,7 +187,7 @@ private function getDependentIndexerIds(string $indexerId) $this->getDependentIndexerIds($id) ); } - }; + } return array_unique($dependentIndexerIds); } diff --git a/app/code/Magento/Indexer/Model/DimensionModes.php b/app/code/Magento/Indexer/Model/DimensionModes.php index bbdee0ced8662..a9507a6f4d358 100644 --- a/app/code/Magento/Indexer/Model/DimensionModes.php +++ b/app/code/Magento/Indexer/Model/DimensionModes.php @@ -26,7 +26,7 @@ public function __construct(array $dimensions) $result = []; foreach ($dimensions as $dimension) { $result[$dimension->getName()] = $dimension; - }; + } return $result; })(...$dimensions); } diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php index b109b87e61bbf..8ce448d06b8f2 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php @@ -44,7 +44,7 @@ private function isStateReadyForInvoice(OrderInterface $order) $order->getState() === Order::STATE_CLOSED ) { return false; - }; + } return true; } diff --git a/app/code/Magento/TaxImportExport/view/adminhtml/templates/importExportHeader.phtml b/app/code/Magento/TaxImportExport/view/adminhtml/templates/importExportHeader.phtml index 223b3e9888eea..75f04eae82159 100644 --- a/app/code/Magento/TaxImportExport/view/adminhtml/templates/importExportHeader.phtml +++ b/app/code/Magento/TaxImportExport/view/adminhtml/templates/importExportHeader.phtml @@ -2,4 +2,4 @@ /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. - */; + */ diff --git a/app/code/Magento/Theme/Model/Design/Config/Validator.php b/app/code/Magento/Theme/Model/Design/Config/Validator.php index 994eeba317a34..1279d9d9ccd20 100644 --- a/app/code/Magento/Theme/Model/Design/Config/Validator.php +++ b/app/code/Magento/Theme/Model/Design/Config/Validator.php @@ -80,7 +80,7 @@ public function validate(DesignConfigInterface $designConfig) ["templateName" => $name] ) ); - }; + } } } } diff --git a/app/code/Magento/Theme/view/frontend/templates/text.phtml b/app/code/Magento/Theme/view/frontend/templates/text.phtml index 4c4b38132c880..7d00235c0362c 100644 --- a/app/code/Magento/Theme/view/frontend/templates/text.phtml +++ b/app/code/Magento/Theme/view/frontend/templates/text.phtml @@ -10,6 +10,6 @@ if (!empty($attr)) { foreach ($block->getAttributes() as $attribute => $value) { $attributes .= ' ' . $attribute . '="' . $value . '"'; } -}; +} echo '<' . $block->getTag() . $attributes . '>' . $block->getText() . '</' . $block->getTag() . '>'; diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php index e83811042fd8b..c335b66505b0e 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php @@ -180,7 +180,7 @@ public function optionDataProvider() $fixtureOptions[$item['type']] = [ 'optionData' => $item, ]; - }; + } return $fixtureOptions; } @@ -230,7 +230,7 @@ public function optionNegativeDataProvider() $fixtureOptions[$key] = [ 'optionData' => $item, ]; - }; + } return $fixtureOptions; } diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.php index 0b7c31a092280..c08ea7aa9e29b 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.php @@ -87,7 +87,7 @@ public function openTab($tabName) if ($tabHeader->isVisible() && strpos($tabHeader->getAttribute('class'), '_show') === false) { $tabHeader->hover(); $tabHeader->click(); - }; + } return $this; } diff --git a/dev/tests/functional/tests/app/Magento/ImportExport/Test/Fixture/Import/File.php b/dev/tests/functional/tests/app/Magento/ImportExport/Test/Fixture/Import/File.php index 17cfdc31720cc..89f51931f8dc8 100644 --- a/dev/tests/functional/tests/app/Magento/ImportExport/Test/Fixture/Import/File.php +++ b/dev/tests/functional/tests/app/Magento/ImportExport/Test/Fixture/Import/File.php @@ -316,7 +316,7 @@ private function prepareCsv($csvContent) $explodedArray = $compiledData['explodedArray']; } else { $explodedArray[$i] = str_replace('"', '', $explodedArray[$i]); - }; + } } $data = array_diff($explodedArray, ['%to_delete%']); $this->csv[] = $data; diff --git a/dev/tests/integration/testsuite/Magento/Deploy/_files/theme.php b/dev/tests/integration/testsuite/Magento/Deploy/_files/theme.php index ffeca0f16094d..bc190a8519ae9 100644 --- a/dev/tests/integration/testsuite/Magento/Deploy/_files/theme.php +++ b/dev/tests/integration/testsuite/Magento/Deploy/_files/theme.php @@ -24,7 +24,7 @@ function rcopy($src, $destination) // If source is not a directory stop processing if (!is_dir($src)) { return false; - }; + } // If the destination directory does not exist create it // If the destination directory could not be created stop processing diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message_rollback.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message_rollback.php index 22307b4d83956..cd17183be7f78 100644 --- a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message_rollback.php +++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message_rollback.php @@ -20,7 +20,7 @@ if ($product->getId()) { $product->delete(); } -}; +} $quote->delete(); $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); 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 f204019988b79..46bdd3dd666df 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 @@ -97,7 +97,7 @@ public function testAcl() $inheritanceMessage = "Backend controller $className have to inherit " . AbstractAction::class; $errorMessages[] = $inheritanceMessage; continue; - }; + } $isAclRedefinedInTheChildClass = $this->isConstantOverwritten($controllerClass) || $this->isMethodOverwritten($controllerClass); diff --git a/lib/internal/Magento/Framework/Indexer/Config/DependencyInfoProvider.php b/lib/internal/Magento/Framework/Indexer/Config/DependencyInfoProvider.php index c9d7c8a35b243..661f9f9c0ff80 100644 --- a/lib/internal/Magento/Framework/Indexer/Config/DependencyInfoProvider.php +++ b/lib/internal/Magento/Framework/Indexer/Config/DependencyInfoProvider.php @@ -49,7 +49,7 @@ public function getIndexerIdsToRunAfter(string $indexerId): array if (array_search($indexerId, $indexerData['dependencies']) !== false) { $result[] = $id; } - }; + } return $result; } diff --git a/lib/internal/Magento/Framework/Setup/OldDbValidator.php b/lib/internal/Magento/Framework/Setup/OldDbValidator.php index 005f7bdd713be..34f916674ca56 100644 --- a/lib/internal/Magento/Framework/Setup/OldDbValidator.php +++ b/lib/internal/Magento/Framework/Setup/OldDbValidator.php @@ -47,7 +47,7 @@ public function getNotUpToDateMessage(): string $requiredVersion = $versionParser->parseConstraints('>' . $error[DbVersionInfo::KEY_REQUIRED]); if ($requiredVersion->matches($currentVersion)) { $codebaseUpdateNeeded = true; - }; + } $messages[] = sprintf( "<info>%20s %10s: %11s -> %-11s</info>", diff --git a/lib/internal/Magento/Framework/TestFramework/Unit/Autoloader/GeneratedClassesAutoloader.php b/lib/internal/Magento/Framework/TestFramework/Unit/Autoloader/GeneratedClassesAutoloader.php index 03c7d85251ac4..2d8348f64a5af 100644 --- a/lib/internal/Magento/Framework/TestFramework/Unit/Autoloader/GeneratedClassesAutoloader.php +++ b/lib/internal/Magento/Framework/TestFramework/Unit/Autoloader/GeneratedClassesAutoloader.php @@ -65,7 +65,7 @@ public function load($className) include $classSourceFile; return true; } - }; + } } return false; From ba7630ba98d8fd1196497685a1c5c14586864e9c Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Wed, 24 Oct 2018 11:57:26 -0500 Subject: [PATCH 475/812] MAGETWO-95445: Category Flat Data indexer doesnt show status as reindex required after deleting store/storeview - Fix static test failures --- .../Catalog/Model/Indexer/Category/Flat/Action/Full.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php index 624001b498449..a62e3d8f83b85 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php @@ -183,7 +183,8 @@ private function getActualStoreTablesForCategoryFlat(): array foreach ($this->storeManager->getStores() as $store) { $actualStoreTables[] = sprintf( '%s_store_%s', - $this->connection->getTableName('catalog_category_flat'), $store->getId() + $this->connection->getTableName('catalog_category_flat'), + $store->getId() ); } From 86e035f3ba615cb5e1bb3ff0e4821b82a57fe7fe Mon Sep 17 00:00:00 2001 From: Tomash Khamlai <tomash.khamlai@gmail.com> Date: Wed, 24 Oct 2018 21:17:45 +0300 Subject: [PATCH 476/812] Cover \Magento\CheckoutAgreements\Model\ResourceModel\Agreement\Grid\Collection class with Integration test --- .../Model/ResourceModel/Grid/CollectionTest.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php b/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php index 2f3112e705c94..bc098cf1bd0ec 100644 --- a/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/CheckoutAgreements/Model/ResourceModel/Grid/CollectionTest.php @@ -25,7 +25,8 @@ class CollectionTest extends \PHPUnit\Framework\TestCase */ public function setUp() { - $this->collection = Bootstrap::getObjectManager()->create(Collection::class); + $this->collection = Bootstrap::getObjectManager() + ->create(Collection::class); } /** @@ -35,7 +36,9 @@ public function setUp() */ public function testAddStoresToFilter(): void { - $collectionSize = $this->collection->addStoreFilter(1)->load(false, false)->getSize(); + $collectionSize = $this->collection->addStoreFilter(1) + ->load(false, false) + ->getSize(); $this->assertEquals(2, $collectionSize); } } From 2fcc1830d0a3a24dce25f986c46b97d15f3c4bae Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 24 Oct 2018 22:36:36 +0300 Subject: [PATCH 477/812] graphQl-44: added ComplexTextValue to graphQl module --- .../Resolver/Product/ProductTextAttribute.php | 30 +++++++++- .../ProductTextAttribute/HtmlContent.php | 60 ------------------- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 7 --- .../CatalogGraphQl/etc/schema.graphqls | 8 +-- .../Resolver/ComplexTextValue/HtmlFormat.php | 38 ++++++++++++ app/code/Magento/GraphQl/etc/schema.graphqls | 4 ++ 6 files changed, 71 insertions(+), 76 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php create mode 100644 app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php index 171e84a65aba4..febcd12f0e96f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php @@ -10,12 +10,29 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Catalog\Model\Product; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Catalog\Helper\Output as OutputHelper; /** - * Resolve rendered content for text attributes + * Resolve rendered content for attributes where HTML content is allowed */ class ProductTextAttribute implements ResolverInterface { + /** + * @var OutputHelper + */ + private $outputHelper; + + /** + * @param OutputHelper $outputHelper + */ + public function __construct( + OutputHelper $outputHelper + ) { + $this->outputHelper = $outputHelper; + } + /** * @inheritdoc */ @@ -26,8 +43,15 @@ public function resolve( array $value = null, array $args = null ): array { - $value['field'] = $field->getName(); + if (!isset($value['model'])) { + throw new GraphQlInputException(__('"model" value should be specified')); + } + + /* @var $product Product */ + $product = $value['model']; + $fieldName = $field->getName(); + $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - return $value; + return ['html' => $renderedValue]; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php deleted file mode 100644 index 724d0826dbb3d..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute/HtmlContent.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute; - -use Magento\Catalog\Model\Product; -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Catalog\Helper\Output as OutputHelper; - -/** - * HTML content of Product Text Attribute - */ -class HtmlContent implements ResolverInterface -{ - /** - * @var OutputHelper - */ - private $outputHelper; - - /** - * @param OutputHelper $outputHelper - */ - public function __construct( - OutputHelper $outputHelper - ) { - $this->outputHelper = $outputHelper; - } - - /** - * @inheritdoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ): ?string { - if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); - } - if (!isset($value['field'])) { - throw new GraphQlInputException(__('"field" value should be specified')); - } - - /* @var $product Product */ - $product = $value['model']; - $fieldName = $value['field']; - $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - - return $renderedValue; - } -} diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 8d4ca97001d3d..68a292ede6b4a 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -63,13 +63,6 @@ <argument name="collectionProcessor" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor</argument> </arguments> </type> - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\FormatList"> - <arguments> - <argument name="formats" xsi:type="array"> - <item name="html" xsi:type="string">Magento\CatalogGraphQl\Model\Resolver\Product\ProductTextAttribute\Html</item> - </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"> diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index ad724c18a5c9a..fb7dd4ee2c8f0 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ProductTextAttribute @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") - short_description: ProductTextAttribute @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + description: ComplexTextValue @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + short_description: ComplexTextValue @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") @@ -556,7 +556,3 @@ type SortFields @doc(description: "SortFields contains a default value for sort default: String @doc(description: "Default value of sort fields") options: [SortField] @doc(description: "Available sort fields") } - -type ProductTextAttribute @doc(description: "Product text attribute.") { - html: String @doc(description: "Attribute HTML content") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute\\HtmlContent") -} diff --git a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php new file mode 100644 index 0000000000000..2ec4d24017b0e --- /dev/null +++ b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php @@ -0,0 +1,38 @@ +<?php +/** + * @author Atwix Team + * @copyright Copyright (c) 2018 Atwix (https://www.atwix.com/) + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Model\Resolver\ComplexTextValue; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; + +/** + * HTML format for complex text value. + * + * Initially, a value from parent resolver should be in HTML format, therefore, there is no any customization. + */ +class HtmlFormat implements ResolverInterface +{ + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ): ?string { + if (!isset($value['html'])) { + throw new GraphQlInputException(__('"html" value should be specified')); + } + + return $value['html']; + } +} diff --git a/app/code/Magento/GraphQl/etc/schema.graphqls b/app/code/Magento/GraphQl/etc/schema.graphqls index c6651cdde0cb3..8923776a63bcf 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphqls +++ b/app/code/Magento/GraphQl/etc/schema.graphqls @@ -35,3 +35,7 @@ enum SortEnum @doc(description: "This enumeration indicates whether to return re ASC DESC } + +type ComplexTextValue { + html: String! @doc(description: "HTML format") @resolver(class: "\\Magento\\GraphQl\\Model\\Resolver\\ComplexTextValue\\HtmlFormat") +} From 6bb825873812cff3ab77d71f1f3542d40aae2b85 Mon Sep 17 00:00:00 2001 From: ashutosh <ashutosh045@webkul.com> Date: Thu, 25 Oct 2018 01:07:09 +0530 Subject: [PATCH 478/812] fixed Product Advanced Pricing design issue #18775 --- app/code/Magento/Ui/view/base/web/templates/form/field.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/templates/form/field.html b/app/code/Magento/Ui/view/base/web/templates/form/field.html index ed84e158819a2..6a095b4da14ed 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/field.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/field.html @@ -8,8 +8,8 @@ visible="visible" css="$data.additionalClasses" attr="'data-index': index"> - <div class="admin__field-label"> - <label if="$data.label" visible="$data.labelVisible" attr="for: uid"> + <div class="admin__field-label" visible="$data.labelVisible"> + <label if="$data.label" attr="for: uid"> <span translate="label" attr="'data-config-scope': $data.scopeLabel" /> </label> </div> From be525d11b45746670822462ab5c1125fd2aca7de Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 24 Oct 2018 23:13:05 +0300 Subject: [PATCH 479/812] graphQl-44: refactored resolver name --- ...oductTextAttribute.php => ProductComplexTextAttribute.php} | 2 +- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 4 ++-- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename app/code/Magento/CatalogGraphQl/Model/Resolver/Product/{ProductTextAttribute.php => ProductComplexTextAttribute.php} (95%) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php similarity index 95% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php index febcd12f0e96f..7cf7225d0f61c 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php @@ -17,7 +17,7 @@ /** * Resolve rendered content for attributes where HTML content is allowed */ -class ProductTextAttribute implements ResolverInterface +class ProductComplexTextAttribute implements ResolverInterface { /** * @var OutputHelper diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index fb7dd4ee2c8f0..423283bdda7b0 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId") name: String @doc(description: "The product name. Customers use this name to identify the product.") sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer") - description: ComplexTextValue @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") - short_description: ComplexTextValue @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductTextAttribute") + description: ComplexTextValue @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductComplexTextAttribute") + short_description: ComplexTextValue @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductComplexTextAttribute") special_price: Float @doc(description: "The discounted price of the product") special_from_date: String @doc(description: "The beginning date that a product has a special price") special_to_date: String @doc(description: "The end date that a product has a special price") 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 615e50f640380..1ab7ed5890472 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -266,7 +266,7 @@ public function testQueryAllFieldsSimpleProduct() $this->assertArrayHasKey(0, $response['products']['items']); $this->assertBaseFields($product, $response['products']['items'][0]); $this->assertEavAttributes($product, $response['products']['items'][0]); - $this->assertTextEavAttributes($product, $response['products']['items'][0]); + $this->assertComplexTextAttributes($product, $response['products']['items'][0]); $this->assertOptions($product, $response['products']['items'][0]); $this->assertTierPrices($product, $response['products']['items'][0]); $this->assertArrayHasKey('websites', $response['products']['items'][0]); @@ -950,7 +950,7 @@ private function assertEavAttributes($product, $actualResponse) * @param ProductInterface $product * @param array $actualResponse */ - private function assertTextEavAttributes($product, $actualResponse) + private function assertComplexTextAttributes($product, $actualResponse) { $eavAttributes = [ 'description', From 1a745a5db170b77ed92b6d71444bc8c8e0f0aa3e Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 24 Oct 2018 15:47:58 -0500 Subject: [PATCH 480/812] MAGETWO-95798: All country state's are shown for USA when shipping form has custom address attributes. --- .../Ui/view/base/web/js/form/element/region.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/region.js b/app/code/Magento/Ui/view/base/web/js/form/element/region.js index 45d38b339b50b..f6eafcf49284d 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/region.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/region.js @@ -78,13 +78,12 @@ define([ * @param {String} field */ filter: function (value, field) { - var country = registry.get(this.parentName + '.' + 'country_id'), - option; + var superFn = this._super; - if (country) { - option = country.indexedOptions[value]; + registry.get(this.parentName + '.' + 'country_id', function (country) { + var option = country.indexedOptions[value]; - this._super(value, field); + superFn.call(this, value, field); if (option && option['is_region_visible'] === false) { // hide select and corresponding text input field if region must not be shown for selected country @@ -94,7 +93,7 @@ define([ this.toggleInput(false); } } - } + }.bind(this)); } }); }); From e5f866d185489d85248134da0aec7f20df468ff1 Mon Sep 17 00:00:00 2001 From: GwanYeong Kim <gy741.kim@gmail.com> Date: Thu, 25 Oct 2018 09:28:34 +0900 Subject: [PATCH 481/812] Remove unnecessary conditional statements --- .../Magento/User/Controller/Adminhtml/User/Role/SaveRole.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php index 44862f1fce2a0..4a9b98f214ee4 100644 --- a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php +++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php @@ -59,9 +59,8 @@ private function getSecurityCookie() { if (!($this->securityCookie instanceof SecurityCookie)) { return \Magento\Framework\App\ObjectManager::getInstance()->get(SecurityCookie::class); - } else { - return $this->securityCookie; } + return $this->securityCookie; } /** From 9d958bbb4103361b2004dcc620a5c9b1b6e4437b Mon Sep 17 00:00:00 2001 From: Stas Puga <stas.puga@transoftgroup.com> Date: Thu, 25 Oct 2018 10:40:02 +0300 Subject: [PATCH 482/812] MAGETWO-95517: Add different types of products on the quote including gift card --- .../Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index 73025023c23c8..45c6c90a76973 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -25,7 +25,6 @@ <argument name="ProductAttribute" type="string"/> </arguments> <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> <fillField selector="{{AdminProductAttributeGridSection.GridFilterFrontEndLabel}}" userInput="{{ProductAttribute}}" stepKey="navigateToAttributeEditPage1" /> <click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="navigateToAttributeEditPage2" /> <waitForPageLoad stepKey="waitForPageLoad2" /> From 6e9d5e5fcda4ce91ef25559bb946c8e52e777148 Mon Sep 17 00:00:00 2001 From: Janak <janak@krishtechnolabs.com> Date: Tue, 16 Oct 2018 14:26:48 +0530 Subject: [PATCH 483/812] Fix customer unsubscribed issue --- app/code/Magento/Newsletter/Model/Subscriber.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php index 03976dfcdc197..c58c2bbf3ba3e 100644 --- a/app/code/Magento/Newsletter/Model/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/Subscriber.php @@ -597,6 +597,8 @@ protected function _updateCustomerSubscription($customerId, $subscribe) } elseif (($this->getStatus() == self::STATUS_UNCONFIRMED) && ($customerData->getConfirmation() === null)) { $status = self::STATUS_SUBSCRIBED; $sendInformationEmail = true; + } elseif (($this->getStatus() == self::STATUS_NOT_ACTIVE) && ($customerData->getConfirmation() === null)) { + $status = self::STATUS_NOT_ACTIVE; } else { $status = self::STATUS_UNSUBSCRIBED; } From 069195ce52b458f6ec9dbcc2907c27722e0f7990 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Thu, 25 Oct 2018 11:44:36 +0300 Subject: [PATCH 484/812] Added form fieldset before html to \Magento\Framework\Data\Form\Element\Fieldset in getElementHtml() method --- lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php b/lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php index 66b1299b98696..90482ab55fc71 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php @@ -43,7 +43,8 @@ public function __construct( */ public function getElementHtml() { - $html = '<fieldset id="' . $this->getHtmlId() . '"' . $this->serialize( + $html = $this->getBeforeElementHtml(); + $html .= '<fieldset area-hidden="false" id="' . $this->getHtmlId() . '"' . $this->serialize( ['class'] ) . $this->_getUiId() . '>' . "\n"; if ($this->getLegend()) { From 42e3fd5fa39beee02c9f03e7cda6a1165e34482e Mon Sep 17 00:00:00 2001 From: DmytroPaidych <dimonovp@gmail.com> Date: Thu, 25 Oct 2018 02:01:26 -0700 Subject: [PATCH 485/812] MAGETWO-95520: Verify that Catalog Price Rule and Customer Group Membership are persisted under long-term cookie --- .../Mftf/ActionGroup/AdminProductAttributeActionGroup.xml | 1 - .../Magento/Persistent/Test/Mftf/Data/PersistentData.xml | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index 45c6c90a76973..ddd73b4191afc 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -13,7 +13,6 @@ <argument name="ProductAttribute"/> </arguments> <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> <fillField selector="{{AdminProductAttributeGridSection.FilterByAttributeCode}}" userInput="{{ProductAttribute.attribute_code}}" stepKey="setAttributeCode"/> <click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="searchForAttributeFromTheGrid"/> diff --git a/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml b/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml index 3d42ae6da81a5..39e55693811e9 100644 --- a/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml +++ b/app/code/Magento/Persistent/Test/Mftf/Data/PersistentData.xml @@ -22,16 +22,16 @@ </entity> <entity name="PersistentLogoutClearEnabled" type="persistent_config_state"> - <requiredEntity type="persistent_options_logout_clear">persistentEnabledLogoutClear</requiredEntity> + <requiredEntity type="persistent_options_logout_clear">PersistentEnabledLogoutClear</requiredEntity> </entity> - <entity name="persistentEnabledLogoutClear" type="logout_clear"> + <entity name="PersistentEnabledLogoutClear" type="logout_clear"> <data key="value">1</data> </entity> <entity name="PersistentLogoutClearDisable" type="persistent_config_state"> - <requiredEntity type="persistent_options_logout_clear">persistentDisableLogoutClear</requiredEntity> + <requiredEntity type="persistent_options_logout_clear">PersistentDisableLogoutClear</requiredEntity> </entity> - <entity name="persistentDisableLogoutClear" type="logout_clear"> + <entity name="PersistentDisableLogoutClear" type="logout_clear"> <data key="value">0</data> </entity> </entities> From 4349d022166c905e4bd77f3bfb36118c7310ff19 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 25 Oct 2018 11:08:56 +0200 Subject: [PATCH 486/812] Run tests without magento installation --- dev/travis/before_script.sh | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index c27e65d3897c7..135152928539c 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -138,25 +138,27 @@ case $TEST_SUITE in api-functional) echo "Installing Magento" mysql -uroot -e 'CREATE DATABASE magento2;' - php bin/magento setup:install -q \ - --language="en_US" \ - --timezone="UTC" \ - --currency="USD" \ - --base-url="http://${MAGENTO_HOST_NAME}/" \ - --admin-firstname="John" \ - --admin-lastname="Doe" \ - --backend-frontname="backend" \ - --admin-email="admin@example.com" \ - --admin-user="admin" \ - --use-rewrites=1 \ - --admin-use-security-key=0 \ - --admin-password="123123q" - - echo "Enabling production mode" - php bin/magento deploy:mode:set production +# php bin/magento setup:install -q \ +# --language="en_US" \ +# --timezone="UTC" \ +# --currency="USD" \ +# --base-url="http://${MAGENTO_HOST_NAME}/" \ +# --admin-firstname="John" \ +# --admin-lastname="Doe" \ +# --backend-frontname="backend" \ +# --admin-email="admin@example.com" \ +# --admin-user="admin" \ +# --use-rewrites=1 \ +# --admin-use-security-key=0 \ +# --admin-password="123123q" + +# echo "Enabling production mode" +# php bin/magento deploy:mode:set production echo "Prepare api-functional tests for running" cd dev/tests/api-functional + cp config/install-config-mysql.php.dist config/install-config-mysql.php + sed -e "s?http://localhost/?http://${MAGENTO_HOST_NAME}/?g" --in-place ./config/install-config-mysql.php cp ./phpunit_graphql.xml.dist ./phpunit.xml sed -e "s?magento.url?${MAGENTO_HOST_NAME}?g" --in-place ./phpunit.xml From 6a6079dcde8068dbac8173699ae4450079ed3201 Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Thu, 25 Oct 2018 15:18:26 +0300 Subject: [PATCH 487/812] magento/magento2#18387: catalog:images:resize fails to process all images -> Possible underlying Magento/Framework/DB/Query/Generator issue - fix getCountAllProductImages select and cover class with unit tests. --- .../Model/ResourceModel/Product/Image.php | 8 +- .../Model/ResourceModel/Product/ImageTest.php | 171 ++++++++++++++++++ 2 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php index 123f358be40c8..5a290d5141e80 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php @@ -77,7 +77,13 @@ public function getAllProductImages(): \Generator */ public function getCountAllProductImages(): int { - $select = $this->getVisibleImagesSelect()->reset('columns')->columns('count(*)'); + $select = $this->getVisibleImagesSelect() + ->reset('columns') + ->reset('distinct') + ->columns( + new \Zend_Db_Expr('count(distinct value)') + ); + return (int) $this->connection->fetchOne($select); } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php new file mode 100644 index 0000000000000..16e245ba640cb --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php @@ -0,0 +1,171 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Test\Unit\Model\ResourceModel\Product; + +use Magento\Catalog\Model\ResourceModel\Product\Image; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Query\Generator; +use Magento\Framework\DB\Select; +use Magento\Framework\App\ResourceConnection; +use Magento\Catalog\Model\ResourceModel\Product\Gallery; + +class ImageTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var AdapterInterface | \PHPUnit_Framework_MockObject_MockObject + */ + protected $connectionMock; + + /** + * @var Generator | \PHPUnit_Framework_MockObject_MockObject + */ + protected $generatorMock; + + /** + * @var ResourceConnection | \PHPUnit_Framework_MockObject_MockObject + */ + protected $resourceMock; + + /** + * @var Image + */ + protected $imageModel; + + /** + * @var int + */ + protected $imagesCount = 50; + + /** + * @var int + */ + protected $batchSize = 10; + + protected function setUp(): void + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->connectionMock = $this->createMock(AdapterInterface::class); + + $this->resourceMock = $this->createMock(ResourceConnection::class); + $this->resourceMock->method('getConnection')->willReturn($this->connectionMock); + $this->resourceMock->method('getTableName')->willReturnArgument(0); + + $this->generatorMock = $this->createMock(Generator::class); + + $this->imageModel = $objectManager->getObject( + Image::class, + [ + 'generator' => $this->generatorMock, + 'resourceConnection' => $this->resourceMock, + 'batchSize' => $this->batchSize + ] + ); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function getVisibleImagesSelectMock(): \PHPUnit_Framework_MockObject_MockObject + { + $selectMock = $this->getMockBuilder(Select::class) + ->disableOriginalConstructor() + ->getMock(); + $selectMock->expects($this->once()) + ->method('distinct') + ->willReturnSelf(); + $selectMock->expects($this->once()) + ->method('from') + ->with( + ['images' => Gallery::GALLERY_TABLE], + 'value as filepath' + )->willReturnSelf(); + $selectMock->expects($this->once()) + ->method('where') + ->with('disabled = 0') + ->willReturnSelf(); + + return $selectMock; + } + + public function testGetCountAllProductImages(): void + { + $selectMock = $this->getVisibleImagesSelectMock(); + $selectMock->expects($this->exactly(2)) + ->method('reset') + ->withConsecutive( + ['columns'], + ['distinct'] + )->willReturnSelf(); + $selectMock->expects($this->once()) + ->method('columns') + ->with(new \Zend_Db_Expr('count(distinct value)')) + ->willReturnSelf(); + + $this->connectionMock->expects($this->once()) + ->method('select') + ->willReturn($selectMock); + $this->connectionMock->expects($this->once()) + ->method('fetchOne') + ->with($selectMock) + ->willReturn($this->imagesCount); + + $this->assertSame($this->imagesCount, $this->imageModel->getCountAllProductImages()); + } + + public function testGetAllProductImages(): void + { + $getBatchIteratorMock = function ($selectMock, $imagesCount, $batchSize): array { + $result = []; + $count = $imagesCount / $batchSize; + while ($count) { + $count--; + $result[$count] = $selectMock; + } + + return $result; + }; + + $getAllProductImagesSelectFetchResults = function ($batchSize): array { + $result = []; + $count = $batchSize; + while ($count) { + $count--; + $result[$count] = $count; + } + + return $result; + }; + + $this->connectionMock->expects($this->once()) + ->method('select') + ->willReturn($this->getVisibleImagesSelectMock()); + + $fetchResult = $getAllProductImagesSelectFetchResults($this->batchSize); + $this->connectionMock->expects($this->exactly($this->imagesCount / $this->batchSize)) + ->method('fetchAll') + ->willReturn($fetchResult); + + /** @var Select | \PHPUnit_Framework_MockObject_MockObject $selectMock */ + $selectMock = $this->getMockBuilder(Select::class) + ->disableOriginalConstructor() + ->getMock(); + + $batchIteratorMock = $getBatchIteratorMock($selectMock, $this->imagesCount, $this->batchSize); + $this->generatorMock->expects($this->once()) + ->method('generate') + ->with( + 'value_id', + $selectMock, + $this->batchSize, + \Magento\Framework\DB\Query\BatchIteratorInterface::NON_UNIQUE_FIELD_ITERATOR + )->willReturn($batchIteratorMock); + + $this->assertCount($this->imagesCount, $this->imageModel->getAllProductImages()); + } +} From ccfffbc78a4e2c0204c0f16e8b1ff32316f5f7c1 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 25 Oct 2018 14:27:13 +0200 Subject: [PATCH 488/812] Deploy test modules before api-functional tests --- .travis.yml | 4 ++-- dev/travis/before_install.sh | 2 +- dev/travis/before_script.sh | 39 ++++++++++++++++++------------------ 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 930172a9ea6e0..25b18949f0386 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ env: # - TEST_SUITE=integration INTEGRATION_INDEX=2 # - TEST_SUITE=integration INTEGRATION_INDEX=3 # - TEST_SUITE=functional - - TEST_SUITE=api-functional + - TEST_SUITE=graphql-api-functional matrix: exclude: - php: 7.1 @@ -66,4 +66,4 @@ script: - if [ $TEST_SUITE == "functional" ]; then dev/tests/functional/vendor/phpunit/phpunit/phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js"] && [ $TEST_SUITE != "api" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - if [ $TEST_SUITE == "js" ]; then grunt $GRUNT_COMMAND; fi - - if [ $TEST_SUITE == "api-functional" ]; then phpunit -c dev/tests/api-functional; fi + - if [ $TEST_SUITE == "graphql-api-functional" ]; then phpunit -c dev/tests/api-functional; fi diff --git a/dev/travis/before_install.sh b/dev/travis/before_install.sh index 44ba3fd8b74f1..845d70e4e79fd 100755 --- a/dev/travis/before_install.sh +++ b/dev/travis/before_install.sh @@ -34,7 +34,7 @@ if [ $TEST_SUITE == "js" ]; then yarn global add grunt-cli fi -if [ $TEST_SUITE = "functional" ] || [ $TEST_SUITE = "api-functional" ]; then +if [ $TEST_SUITE = "functional" ] || [ $TEST_SUITE = "graphql-api-functional" ]; then # Install apache sudo apt-get update sudo apt-get install apache2 libapache2-mod-fastcgi diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 135152928539c..64591e8112cef 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -135,34 +135,35 @@ case $TEST_SUITE in cd ../../.. ;; - api-functional) + graphql-api-functional) echo "Installing Magento" mysql -uroot -e 'CREATE DATABASE magento2;' -# php bin/magento setup:install -q \ -# --language="en_US" \ -# --timezone="UTC" \ -# --currency="USD" \ -# --base-url="http://${MAGENTO_HOST_NAME}/" \ -# --admin-firstname="John" \ -# --admin-lastname="Doe" \ -# --backend-frontname="backend" \ -# --admin-email="admin@example.com" \ -# --admin-user="admin" \ -# --use-rewrites=1 \ -# --admin-use-security-key=0 \ -# --admin-password="123123q" - -# echo "Enabling production mode" -# php bin/magento deploy:mode:set production + php bin/magento setup:install -q \ + --language="en_US" \ + --timezone="UTC" \ + --currency="USD" \ + --base-url="http://${MAGENTO_HOST_NAME}/" \ + --admin-firstname="John" \ + --admin-lastname="Doe" \ + --backend-frontname="backend" \ + --admin-email="admin@example.com" \ + --admin-user="admin" \ + --use-rewrites=1 \ + --admin-use-security-key=0 \ + --admin-password="123123q" + + echo "Enabling production mode" + php bin/magento deploy:mode:set production echo "Prepare api-functional tests for running" cd dev/tests/api-functional - cp config/install-config-mysql.php.dist config/install-config-mysql.php - sed -e "s?http://localhost/?http://${MAGENTO_HOST_NAME}/?g" --in-place ./config/install-config-mysql.php + cp -r _files/Magento/* ../../../app/code/Magento # Deploy and enable test modules before running tests + php ../../../bin/magento setup:upgrade cp ./phpunit_graphql.xml.dist ./phpunit.xml sed -e "s?magento.url?${MAGENTO_HOST_NAME}?g" --in-place ./phpunit.xml cd ../../.. + php bin/magento setup:upgrade ;; esac From 33f40d63ee1d102e81822341fadeb4cd5af68997 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 25 Oct 2018 14:50:06 +0200 Subject: [PATCH 489/812] Remove redundant setup:upgrade --- .travis.yml | 2 +- dev/travis/before_script.sh | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 25b18949f0386..db42be9f1e217 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,7 +45,7 @@ matrix: - php: 7.1 env: TEST_SUITE=functional - php: 7.1 - env: TEST_SUITE=api-functional + env: TEST_SUITE=graphql-api-functional cache: apt: true directories: diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 64591e8112cef..8b5dcab310418 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -158,7 +158,6 @@ case $TEST_SUITE in echo "Prepare api-functional tests for running" cd dev/tests/api-functional cp -r _files/Magento/* ../../../app/code/Magento # Deploy and enable test modules before running tests - php ../../../bin/magento setup:upgrade cp ./phpunit_graphql.xml.dist ./phpunit.xml sed -e "s?magento.url?${MAGENTO_HOST_NAME}?g" --in-place ./phpunit.xml From 35356efc619f0165dfe04f5762e9af63816569a7 Mon Sep 17 00:00:00 2001 From: stani <sa@webvisum.de> Date: Thu, 25 Oct 2018 14:53:30 +0200 Subject: [PATCH 490/812] magento-engcom/import-export-improvements#51: fix for uploader filepath --- .../Magento/CatalogImportExport/Model/Import/Uploader.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php index e7ffe408cc732..8dc551c407277 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php @@ -113,15 +113,15 @@ public function __construct( \Magento\Framework\Filesystem\File\ReadFactory $readFactory, $filePath = null ) { - if ($filePath !== null) { - $this->_setUploadFile($filePath); - } $this->_imageFactory = $imageFactory; $this->_coreFileStorageDb = $coreFileStorageDb; $this->_coreFileStorage = $coreFileStorage; $this->_validator = $validator; $this->_directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); $this->_readFactory = $readFactory; + if ($filePath !== null) { + $this->_setUploadFile($filePath); + } } /** From 41bf2a1485ead39c75d97cccc819c9cc2091f0ca Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 25 Oct 2018 15:11:04 +0200 Subject: [PATCH 491/812] Enable back other tests --- .travis.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index db42be9f1e217..78b088c9d848d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,14 +25,14 @@ env: - NODE_JS_VERSION=8 - MAGENTO_HOST_NAME="magento2.travis" matrix: -# - TEST_SUITE=unit -# - TEST_SUITE=static -# - TEST_SUITE=js GRUNT_COMMAND=spec -# - TEST_SUITE=js GRUNT_COMMAND=static -# - TEST_SUITE=integration INTEGRATION_INDEX=1 -# - TEST_SUITE=integration INTEGRATION_INDEX=2 -# - TEST_SUITE=integration INTEGRATION_INDEX=3 -# - TEST_SUITE=functional + - TEST_SUITE=unit + - TEST_SUITE=static + - TEST_SUITE=js GRUNT_COMMAND=spec + - TEST_SUITE=js GRUNT_COMMAND=static + - TEST_SUITE=integration INTEGRATION_INDEX=1 + - TEST_SUITE=integration INTEGRATION_INDEX=2 + - TEST_SUITE=integration INTEGRATION_INDEX=3 + - TEST_SUITE=functional - TEST_SUITE=graphql-api-functional matrix: exclude: From 466daaa332e85eee15d3391d0ceead11855e90dd Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Thu, 25 Oct 2018 18:15:55 +0300 Subject: [PATCH 492/812] magento/magento2#18387: catalog:images:resize fails to process all images -> Possible underlying Magento/Framework/DB/Query/Generator issue - fix code style; --- .../Test/Unit/Model/ResourceModel/Product/ImageTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php index 16e245ba640cb..9c783e237ab24 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php @@ -131,7 +131,7 @@ public function testGetAllProductImages(): void return $result; }; - $getAllProductImagesSelectFetchResults = function ($batchSize): array { + $getFetchResults = function ($batchSize): array { $result = []; $count = $batchSize; while ($count) { @@ -146,7 +146,7 @@ public function testGetAllProductImages(): void ->method('select') ->willReturn($this->getVisibleImagesSelectMock()); - $fetchResult = $getAllProductImagesSelectFetchResults($this->batchSize); + $fetchResult = $getFetchResults($this->batchSize); $this->connectionMock->expects($this->exactly($this->imagesCount / $this->batchSize)) ->method('fetchAll') ->willReturn($fetchResult); From f82912dc75d57694b056ca6a7ca198fde1e6b108 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Thu, 25 Oct 2018 18:34:19 +0300 Subject: [PATCH 493/812] graphQl-44: fixed copyrights --- .../GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php index 2ec4d24017b0e..fffca765faba6 100644 --- a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php +++ b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php @@ -1,7 +1,7 @@ <?php /** - * @author Atwix Team - * @copyright Copyright (c) 2018 Atwix (https://www.atwix.com/) + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ declare(strict_types=1); From 992a750e8870e413b0af592ffea819308d448a24 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Tue, 9 Oct 2018 10:36:33 -0500 Subject: [PATCH 494/812] MC-4154: Banner Background Image disappear after saving Schedule Update page of CMS Block - fixed JS console error when saving scheduled update --- lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js index 760e0785a7893..3526abefa233b 100644 --- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js +++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js @@ -129,7 +129,7 @@ define([ removeEvents: function (wysiwygId) { var editor; - if (typeof tinyMceEditors !== 'undefined') { + if (typeof tinyMceEditors !== 'undefined' && tinyMceEditors.get(wysiwygId)) { editor = tinyMceEditors.get(wysiwygId); varienGlobalEvents.removeEventHandler('tinymceChange', editor.onChangeContent); } From 008fe5d2bec2167e29d45001a674de8249e393e7 Mon Sep 17 00:00:00 2001 From: rahul <rahul@webkul.com> Date: Thu, 25 Oct 2018 23:31:03 +0530 Subject: [PATCH 495/812] fixed Translation issue send-friend in send.phtml #18779 --- .../Magento/SendFriend/view/frontend/templates/send.phtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml index 2b25e0efab84a..862ef5fdebc3c 100644 --- a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml +++ b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml @@ -23,7 +23,7 @@ </div> <fieldset class="fieldset"> <div class="field name required"> - <label for="recipients-name<%- data._index_ %>" class="label"><span><?= $block->escapeJs($block->escapeHtml(__('Name'))) ?></span></label> + <label for="recipients-name<%- data._index_ %>" class="label"><span><?= $block->escapeHtml(__('Name')) ?></span></label> <div class="control"> <input name="recipients[name][<%- data._index_ %>]" type="text" title="<?= $block->escapeHtmlAttr(__('Name')) ?>" class="input-text" id="recipients-name<%- data._index_ %>" data-validate="{required:true}"/> @@ -31,7 +31,7 @@ </div> <div class="field email required"> - <label for="recipients-email<%- data._index_ %>" class="label"><span><?= $block->escapeJs($block->escapeHtml(__('Email'))) ?></span></label> + <label for="recipients-email<%- data._index_ %>" class="label"><span><?= $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> <input name="recipients[email][<%- data._index_ %>]" title="<?= $block->escapeHtmlAttr(__('Email')) ?>" id="recipients-email<%- data._index_ %>" type="email" class="input-text" From dd6bcfb3188a5a0e9cbb113be838c222cbf27da2 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 25 Oct 2018 12:23:31 +0300 Subject: [PATCH 496/812] MAGETWO-95880: Fail to install Magento 2.3.0 on cloud --- .../Magento/Config/App/Config/Type/System.php | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 2b65c2791365a..cc31b9ae6e27a 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -131,6 +131,32 @@ public function get($path = '') return $this->getWithParts($path); } + /** + * Merge newly loaded config data into already loaded. + * + * @param array $newData + * @return void + */ + private function mergeData(array $newData): void + { + if (array_key_exists(ScopeInterface::SCOPE_DEFAULT, $newData)) { + //Sometimes new data may contain links to arrays and we don't want that. + $this->data[ScopeInterface::SCOPE_DEFAULT] = (array)$newData[ScopeInterface::SCOPE_DEFAULT]; + unset($newData[ScopeInterface::SCOPE_DEFAULT]); + } + foreach ($newData as $scopeType => $scopeTypeData) { + if (!array_key_exists($scopeType, $this->data)) { + //Sometimes new data may contain links to arrays and we don't want that. + $this->data[$scopeType] = (array)$scopeTypeData; + } else { + foreach ($scopeTypeData as $scopeId => $scopeData) { + //Sometimes new data may contain links to arrays and we don't want that. + $this->data[$scopeType][$scopeId] = (array)$scopeData; + } + } + } + } + /** * Proceed with parts extraction from path. * @@ -143,8 +169,10 @@ private function getWithParts($path) if (count($pathParts) === 1 && $pathParts[0] !== ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$pathParts[0]])) { + //First filling data property with unprocessed data for post-processors to be able to use. $data = $this->readData(); - $this->data = array_replace_recursive($this->data, $this->postProcessor->process($data)); + //Post-processing only the data we know is not yet processed. + $this->mergeData($this->postProcessor->process($data)); } return $this->data[$pathParts[0]]; @@ -154,12 +182,11 @@ private function getWithParts($path) if ($scopeType === ScopeInterface::SCOPE_DEFAULT) { if (!isset($this->data[$scopeType])) { - $this->data = array_replace_recursive( - $this->data, - $scopeData = $this->loadDefaultScopeData($scopeType) - ); + //Adding unprocessed data to the data property so it can be used in post-processing. + $this->mergeData($scopeData = $this->loadDefaultScopeData($scopeType)); + //Only post-processing the data we know is raw. $scopeData = $this->postProcessor->process($scopeData); - $this->data = array_replace_recursive($this->data, $scopeData); + $this->mergeData($scopeData); } return $this->getDataByPathParts($this->data[$scopeType], $pathParts); @@ -169,9 +196,11 @@ private function getWithParts($path) if (!isset($this->data[$scopeType][$scopeId])) { $scopeData = $this->loadScopeData($scopeType, $scopeId); - $this->data = array_replace_recursive($this->data, $scopeData); + //Adding unprocessed data to the data property so it can be used in post-processing. + $this->mergeData($scopeData); + //Only post-processing the data we know is raw. $scopeData = $this->postProcessor->process($scopeData); - $this->data = array_replace_recursive($this->data, $scopeData); + $this->mergeData($scopeData); } return isset($this->data[$scopeType][$scopeId]) From ff5b15ac4c100315927000434550b90e9370d203 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 25 Oct 2018 12:35:10 +0300 Subject: [PATCH 497/812] MAGETWO-95880: Fail to install Magento 2.3.0 on cloud --- app/code/Magento/Config/App/Config/Type/System.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index cc31b9ae6e27a..7f61ded7d8835 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -22,6 +22,7 @@ * * @api * @since 100.1.2 + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class System implements ConfigTypeInterface { From afd779379611a21cc865966c7517e649146e37cc Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 25 Oct 2018 12:47:02 +0300 Subject: [PATCH 498/812] MAGETWO-95880: Fail to install Magento 2.3.0 on cloud --- app/code/Magento/Config/App/Config/Type/System.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 7f61ded7d8835..46b143fd15ab2 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -140,6 +140,7 @@ public function get($path = '') */ private function mergeData(array $newData): void { + return $this->data = array_merge_recursive($this->data, $newData); if (array_key_exists(ScopeInterface::SCOPE_DEFAULT, $newData)) { //Sometimes new data may contain links to arrays and we don't want that. $this->data[ScopeInterface::SCOPE_DEFAULT] = (array)$newData[ScopeInterface::SCOPE_DEFAULT]; From a70858bfe5621fe850cff47b0572661db4cab0ca Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 25 Oct 2018 13:09:00 +0300 Subject: [PATCH 499/812] MAGETWO-95880: Fail to install Magento 2.3.0 on cloud --- app/code/Magento/Config/App/Config/Type/System.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 46b143fd15ab2..7c072dcd1a2aa 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -140,7 +140,8 @@ public function get($path = '') */ private function mergeData(array $newData): void { - return $this->data = array_merge_recursive($this->data, $newData); + $this->data = array_replace_recursive($this->data, $newData); + return; if (array_key_exists(ScopeInterface::SCOPE_DEFAULT, $newData)) { //Sometimes new data may contain links to arrays and we don't want that. $this->data[ScopeInterface::SCOPE_DEFAULT] = (array)$newData[ScopeInterface::SCOPE_DEFAULT]; From 88b030313513aeb7021f6af841be559bb9f426e4 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 25 Oct 2018 13:19:29 +0300 Subject: [PATCH 500/812] MAGETWO-95880: Fail to install Magento 2.3.0 on cloud --- app/code/Magento/Config/App/Config/Type/System.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/Config/App/Config/Type/System.php b/app/code/Magento/Config/App/Config/Type/System.php index 7c072dcd1a2aa..7f61ded7d8835 100644 --- a/app/code/Magento/Config/App/Config/Type/System.php +++ b/app/code/Magento/Config/App/Config/Type/System.php @@ -140,8 +140,6 @@ public function get($path = '') */ private function mergeData(array $newData): void { - $this->data = array_replace_recursive($this->data, $newData); - return; if (array_key_exists(ScopeInterface::SCOPE_DEFAULT, $newData)) { //Sometimes new data may contain links to arrays and we don't want that. $this->data[ScopeInterface::SCOPE_DEFAULT] = (array)$newData[ScopeInterface::SCOPE_DEFAULT]; From afe43948a64f0882112f79eb3dc29fbbb02713e9 Mon Sep 17 00:00:00 2001 From: Tom Richards <tom.r@delegator.com> Date: Thu, 25 Oct 2018 15:30:32 -0400 Subject: [PATCH 501/812] Replace erroneous usage of unsData method --- .../Magento/GroupedProduct/Model/Product/Type/Grouped.php | 2 +- .../Test/Unit/Model/Product/Type/GroupedTest.php | 4 ++-- .../Magento/Reports/Model/Product/Index/AbstractIndex.php | 2 +- .../testsuite/Magento/Newsletter/Controller/ManageTest.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php index 80824d45cb6e5..673450838fb94 100644 --- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php +++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php @@ -236,7 +236,7 @@ public function getAssociatedProducts($product) */ public function flushAssociatedProductsCache($product) { - return $product->unsData($this->_keyAssociatedProducts); + return $product->unsetData($this->_keyAssociatedProducts); } /** diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php index 06c07a8dc34a8..e50d6491a6aca 100644 --- a/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php +++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/Product/Type/GroupedTest.php @@ -611,9 +611,9 @@ public function testPrepareForCartAdvancedZeroQty() public function testFlushAssociatedProductsCache() { - $productMock = $this->createPartialMock(\Magento\Catalog\Model\Product::class, ['unsData']); + $productMock = $this->createPartialMock(\Magento\Catalog\Model\Product::class, ['unsetData']); $productMock->expects($this->once()) - ->method('unsData') + ->method('unsetData') ->with('_cache_instance_associated_products') ->willReturnSelf(); $this->assertEquals($productMock, $this->_model->flushAssociatedProductsCache($productMock)); diff --git a/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php b/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php index 5682892a77c60..56991e290dec6 100644 --- a/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php +++ b/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php @@ -252,7 +252,7 @@ public function clean() public function registerIds($productIds) { $this->_getResource()->registerIds($this, $productIds); - $this->_getSession()->unsData($this->_countCacheKey); + $this->_getSession()->unsetData($this->_countCacheKey); return $this; } } diff --git a/dev/tests/integration/testsuite/Magento/Newsletter/Controller/ManageTest.php b/dev/tests/integration/testsuite/Magento/Newsletter/Controller/ManageTest.php index 5a094eb05c774..175c1c7c6c668 100644 --- a/dev/tests/integration/testsuite/Magento/Newsletter/Controller/ManageTest.php +++ b/dev/tests/integration/testsuite/Magento/Newsletter/Controller/ManageTest.php @@ -40,7 +40,7 @@ protected function setUp() protected function tearDown() { $this->customerSession->setCustomerId(null); - $this->coreSession->unsData('_form_key'); + $this->coreSession->unsetData('_form_key'); } /** From 3d0d8b7674c6798c3907cb77e690f62ef5310592 Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh721@webkul.com> Date: Fri, 26 Oct 2018 01:46:45 +0530 Subject: [PATCH 502/812] Issue #18150 fixed --- app/code/Magento/Backup/Controller/Adminhtml/Index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index.php b/app/code/Magento/Backup/Controller/Adminhtml/Index.php index dcafbc7370d2d..142211fe90a44 100644 --- a/app/code/Magento/Backup/Controller/Adminhtml/Index.php +++ b/app/code/Magento/Backup/Controller/Adminhtml/Index.php @@ -19,7 +19,7 @@ abstract class Index extends \Magento\Backend\App\Action * * @see _isAllowed() */ - const ADMIN_RESOURCE = 'Magento_Backend::backup'; + const ADMIN_RESOURCE = 'Magento_Backup::backup'; /** * Core registry From b85984979deb494d12942446d6a8ab9e876c2d31 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Thu, 25 Oct 2018 16:20:52 -0500 Subject: [PATCH 503/812] Merge remote-tracking branch 'upstream/2.3.0-release' into 2.3.0-release-sync --- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 9cab91ce52bd8..2c003a67598df 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -454,7 +454,9 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() } short_description sku - small_image + small_image { + path + } small_image_label special_from_date special_price From 7f24f769d794792b6a960043c0815ed6c33814bb Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Fri, 26 Oct 2018 11:05:12 +0300 Subject: [PATCH 504/812] magento-engcom/magento2ce#2280: Code style fixes --- .../ProductCategoryCondition.php | 1 + .../Model/Product/Attribute/Repository.php | 14 +++++++------ .../Catalog/Model/ProductCategoryList.php | 1 - .../Model/Import/Product/Validator.php | 20 +++++++++++++++++-- .../Block/Product/ProductsList.php | 2 ++ .../Model/PaymentInformationManagement.php | 8 +++++--- .../Agreement/Grid/Collection.php | 6 +++++- .../GiftMessage/Model/ItemRepository.php | 4 ++-- .../GiftMessage/Model/OrderItemRepository.php | 4 ++-- .../GiftMessage/Model/OrderRepository.php | 4 ++-- .../Console/Command/IndexerReindexCommand.php | 12 ++++++++--- .../Quote/Model/BillingAddressManagement.php | 7 ++++--- .../Model/Order/Validation/CanInvoice.php | 6 ++++++ .../Adminhtml/User/Role/SaveRole.php | 6 ++++++ lib/internal/Magento/Framework/Mview/View.php | 2 ++ .../Framework/Setup/OldDbValidator.php | 6 +++++- .../Magento/Setup/Model/PhpReadinessCheck.php | 2 ++ 17 files changed, 79 insertions(+), 26 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php index d37f97c38a4f6..66a9132ae44b8 100644 --- a/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php +++ b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/ConditionProcessor/ProductCategoryCondition.php @@ -38,6 +38,7 @@ class ProductCategoryCondition implements CustomConditionInterface /** * @param \Magento\Framework\App\ResourceConnection $resourceConnection + * @param \Magento\Catalog\Model\CategoryRepository $categoryRepository */ public function __construct( \Magento\Framework\App\ResourceConnection $resourceConnection, diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php index 48ca12321a250..99edfe5bc7208 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php @@ -11,6 +11,8 @@ use Magento\Framework\Exception\NoSuchEntityException; /** + * Product attribute repository + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Repository implements \Magento\Catalog\Api\ProductAttributeRepositoryInterface @@ -78,7 +80,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function get($attributeCode) { @@ -89,7 +91,7 @@ public function get($attributeCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria) { @@ -100,7 +102,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ @@ -180,7 +182,7 @@ public function save(\Magento\Catalog\Api\Data\ProductAttributeInterface $attrib } /** - * {@inheritdoc} + * @inheritdoc */ public function delete(\Magento\Catalog\Api\Data\ProductAttributeInterface $attribute) { @@ -189,7 +191,7 @@ public function delete(\Magento\Catalog\Api\Data\ProductAttributeInterface $attr } /** - * {@inheritdoc} + * @inheritdoc */ public function deleteById($attributeCode) { @@ -200,7 +202,7 @@ public function deleteById($attributeCode) } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function getCustomAttributesMetadata($dataObjectClassName = null) diff --git a/app/code/Magento/Catalog/Model/ProductCategoryList.php b/app/code/Magento/Catalog/Model/ProductCategoryList.php index c8b075ffb494e..c3a88a505c516 100644 --- a/app/code/Magento/Catalog/Model/ProductCategoryList.php +++ b/app/code/Magento/Catalog/Model/ProductCategoryList.php @@ -84,7 +84,6 @@ public function getCategoryIds($productId) 'intval', $this->productResource->getConnection()->fetchCol($unionSelect) ); - } return $this->categoryIdList[$productId]; diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php index 21f7f87875e12..4b7416f6ad9a6 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php @@ -61,6 +61,8 @@ public function __construct( } /** + * Text validation + * * @param mixed $attrCode * @param string $type * @return bool @@ -108,6 +110,8 @@ private function validateOption($attrCode, $possibleOptions, $value) } /** + * Numeric validation + * * @param mixed $attrCode * @param string $type * @return bool @@ -135,6 +139,8 @@ protected function numericValidation($attrCode, $type) } /** + * Is required attribute valid + * * @param string $attrCode * @param array $attributeParams * @param array $rowData @@ -162,6 +168,8 @@ public function isRequiredAttributeValid($attrCode, array $attributeParams, arra } /** + * Is attribute valid + * * @param string $attrCode * @param array $attrParams * @param array $rowData @@ -258,6 +266,8 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData) } /** + * Set invalid attribute + * * @param string|null $attribute * @return void * @since 100.1.0 @@ -268,6 +278,8 @@ protected function setInvalidAttribute($attribute) } /** + * Get invalid attribute + * * @return string * @since 100.1.0 */ @@ -277,6 +289,8 @@ public function getInvalidAttribute() } /** + * Is valid attributes + * * @return bool * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ @@ -303,7 +317,7 @@ protected function isValidAttributes() } /** - * {@inheritdoc} + * @inheritdoc */ public function isValid($value) { @@ -334,6 +348,8 @@ public function getRowScope(array $rowData) } /** + * Init + * * @param \Magento\CatalogImportExport\Model\Import\Product $context * @return $this */ @@ -344,4 +360,4 @@ public function init($context) $validator->init($context); } } -} \ No newline at end of file +} diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index a0cfc08406189..55f4d67273379 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -410,6 +410,8 @@ private function getPriceCurrency() } /** + * Get widget block name + * * @return string */ private function getWidgetPagerBlockName() diff --git a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php index 947f7b896f67a..d2bd680aa38f3 100644 --- a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php +++ b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php @@ -9,6 +9,8 @@ use Magento\Framework\Exception\CouldNotSaveException; /** + * Payment information management + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInformationManagementInterface @@ -72,7 +74,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritdoc */ public function savePaymentInformationAndPlaceOrder( $cartId, @@ -98,7 +100,7 @@ public function savePaymentInformationAndPlaceOrder( } /** - * {@inheritDoc} + * @inheritdoc */ public function savePaymentInformation( $cartId, @@ -124,7 +126,7 @@ public function savePaymentInformation( } /** - * {@inheritDoc} + * @inheritdoc */ public function getPaymentInformation($cartId) { diff --git a/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php b/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php index 78ad7b32330ad..bc055ca9f663b 100644 --- a/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php +++ b/app/code/Magento/CheckoutAgreements/Model/ResourceModel/Agreement/Grid/Collection.php @@ -14,7 +14,7 @@ class Collection extends \Magento\CheckoutAgreements\Model\ResourceModel\Agreeme { /** - * {@inheritdoc} + * @inheritdoc */ public function load($printQuery = false, $logQuery = false) { @@ -30,6 +30,8 @@ public function load($printQuery = false, $logQuery = false) } /** + * Add stores to result + * * @return void */ private function addStoresToResult() @@ -56,6 +58,8 @@ private function addStoresToResult() } /** + * Get stores for agreements + * * @return array */ private function getStoresForAgreements() diff --git a/app/code/Magento/GiftMessage/Model/ItemRepository.php b/app/code/Magento/GiftMessage/Model/ItemRepository.php index dce60079e43e3..aa65bf94f361a 100644 --- a/app/code/Magento/GiftMessage/Model/ItemRepository.php +++ b/app/code/Magento/GiftMessage/Model/ItemRepository.php @@ -74,7 +74,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritdoc */ public function get($cartId, $itemId) { @@ -103,7 +103,7 @@ public function get($cartId, $itemId) } /** - * {@inheritDoc} + * @inheritdoc */ public function save($cartId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage, $itemId) { diff --git a/app/code/Magento/GiftMessage/Model/OrderItemRepository.php b/app/code/Magento/GiftMessage/Model/OrderItemRepository.php index 6cfcd485f7645..445ba54ac4d9c 100644 --- a/app/code/Magento/GiftMessage/Model/OrderItemRepository.php +++ b/app/code/Magento/GiftMessage/Model/OrderItemRepository.php @@ -80,7 +80,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritdoc */ public function get($orderId, $orderItemId) { @@ -111,7 +111,7 @@ public function get($orderId, $orderItemId) } /** - * {@inheritDoc} + * @inheritdoc */ public function save($orderId, $orderItemId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage) { diff --git a/app/code/Magento/GiftMessage/Model/OrderRepository.php b/app/code/Magento/GiftMessage/Model/OrderRepository.php index 88d1adf92ed0b..e943fa2a3b084 100644 --- a/app/code/Magento/GiftMessage/Model/OrderRepository.php +++ b/app/code/Magento/GiftMessage/Model/OrderRepository.php @@ -74,7 +74,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritdoc */ public function get($orderId) { @@ -98,7 +98,7 @@ public function get($orderId) } /** - * {@inheritDoc} + * @inheritdoc */ public function save($orderId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage) { diff --git a/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php b/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php index 6d0716a6f1c27..fffa4503e14a7 100644 --- a/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php +++ b/app/code/Magento/Indexer/Console/Command/IndexerReindexCommand.php @@ -58,7 +58,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ protected function configure() { @@ -70,7 +70,7 @@ protected function configure() } /** - * {@inheritdoc} + * @inheritdoc */ protected function execute(InputInterface $input, OutputInterface $output) { @@ -105,7 +105,9 @@ protected function execute(InputInterface $input, OutputInterface $output) } /** - * {@inheritdoc} Returns the ordered list of specified indexers and related indexers. + * @inheritdoc + * + * Returns the ordered list of specified indexers and related indexers. */ protected function getIndexers(InputInterface $input) { @@ -272,6 +274,8 @@ private function getConfig() } /** + * Get indexer registry + * * @return IndexerRegistry * @deprecated 100.2.0 */ @@ -284,6 +288,8 @@ private function getIndexerRegistry() } /** + * Get dependency info provider + * * @return DependencyInfoProvider * @deprecated 100.2.0 */ diff --git a/app/code/Magento/Quote/Model/BillingAddressManagement.php b/app/code/Magento/Quote/Model/BillingAddressManagement.php index e8af185b8c2f0..bc055e71c662e 100644 --- a/app/code/Magento/Quote/Model/BillingAddressManagement.php +++ b/app/code/Magento/Quote/Model/BillingAddressManagement.php @@ -14,7 +14,6 @@ /** * Quote billing address write service object. - * */ class BillingAddressManagement implements BillingAddressManagementInterface { @@ -70,7 +69,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritdoc * @SuppressWarnings(PHPMD.NPathComplexity) */ public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address, $useForShipping = false) @@ -92,7 +91,7 @@ public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $addres } /** - * {@inheritDoc} + * @inheritdoc */ public function get($cartId) { @@ -101,6 +100,8 @@ public function get($cartId) } /** + * Get shipping address assignment + * * @return \Magento\Quote\Model\ShippingAddressAssignment * @deprecated 100.2.0 */ diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php index 8ce448d06b8f2..7b346a232ab95 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php @@ -15,6 +15,8 @@ class CanInvoice implements ValidatorInterface { /** + * Validate + * * @param OrderInterface $entity * @return array */ @@ -32,6 +34,8 @@ public function validate($entity) } /** + * Is state ready for invoice + * * @param OrderInterface $order * @return bool */ @@ -50,6 +54,8 @@ private function isStateReadyForInvoice(OrderInterface $order) } /** + * Can invoice + * * @param OrderInterface $order * @return bool */ diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php index 4a9b98f214ee4..acd3430f5c25a 100644 --- a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php +++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php @@ -15,6 +15,8 @@ use Magento\Security\Model\SecurityCookie; /** + * Save role controller + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class SaveRole extends \Magento\User\Controller\Adminhtml\User\Role implements HttpPostActionInterface @@ -150,6 +152,8 @@ protected function validateUser() } /** + * Process previous users + * * @param \Magento\Authorization\Model\Role $role * @return $this * @throws \Exception @@ -206,6 +210,8 @@ protected function _deleteUserFromRole($userId, $roleId) } /** + * Save data to session and redirect + * * @param \Magento\Authorization\Model\Role $role * @param array $data * @param \Magento\Backend\Model\View\Result\Redirect $resultRedirect diff --git a/lib/internal/Magento/Framework/Mview/View.php b/lib/internal/Magento/Framework/Mview/View.php index 589034886010f..1b32238813f86 100644 --- a/lib/internal/Magento/Framework/Mview/View.php +++ b/lib/internal/Magento/Framework/Mview/View.php @@ -10,6 +10,8 @@ use Magento\Framework\Mview\View\SubscriptionFactory; /** + * Mview + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class View extends \Magento\Framework\DataObject implements ViewInterface diff --git a/lib/internal/Magento/Framework/Setup/OldDbValidator.php b/lib/internal/Magento/Framework/Setup/OldDbValidator.php index 34f916674ca56..4c224a6c713ef 100644 --- a/lib/internal/Magento/Framework/Setup/OldDbValidator.php +++ b/lib/internal/Magento/Framework/Setup/OldDbValidator.php @@ -11,7 +11,9 @@ use Magento\Framework\Module\DbVersionInfo; /** - * Old Validator for database is used in order to support backward compatability of modules that are installed + * Old Validator for database + * + * Used in order to support backward compatability of modules that are installed * in old way (with Install/Upgrade Schema/Data scripts) */ class OldDbValidator implements UpToDateValidatorInterface @@ -63,6 +65,8 @@ public function getNotUpToDateMessage(): string } /** + * Is up to date + * * @return bool */ public function isUpToDate(): bool diff --git a/setup/src/Magento/Setup/Model/PhpReadinessCheck.php b/setup/src/Magento/Setup/Model/PhpReadinessCheck.php index 98da6cb7a5e0f..86a377c8edc62 100644 --- a/setup/src/Magento/Setup/Model/PhpReadinessCheck.php +++ b/setup/src/Magento/Setup/Model/PhpReadinessCheck.php @@ -179,6 +179,7 @@ public function checkPhpExtensions() /** * Checks php memory limit + * * @return array */ public function checkMemoryLimit() @@ -235,6 +236,7 @@ public function checkMemoryLimit() /** * Checks if xdebug.max_nesting_level is set 200 or more + * * @return array */ private function checkXDebugNestedLevel() From 81527754cc8dcd78cd798e522cc6d611d4a19dd5 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Fri, 26 Oct 2018 11:54:14 +0300 Subject: [PATCH 505/812] ENGCOM-3259: [Forwardport] 17516: added Australian states #18774. Fix static and database compare tests. --- .../Directory/Setup/Patch/Data/AddDataForAustralia.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php index 0abadf7153424..e71abf3a58571 100644 --- a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php @@ -39,7 +39,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function apply() { @@ -71,17 +71,19 @@ private function getDataForAustralia() } /** - * {@inheritdoc} + * @inheritdoc */ public static function getDependencies() { return [ InitializeDirectoryData::class, + AddDataForCroatia::class, + AddDataForIndia::class, ]; } /** - * {@inheritdoc} + * @inheritdoc */ public static function getVersion() { @@ -89,7 +91,7 @@ public static function getVersion() } /** - * {@inheritdoc} + * @inheritdoc */ public function getAliases() { From 755ef37b3a1e35b59f38652e69f1c26ea1ff56b4 Mon Sep 17 00:00:00 2001 From: Stas Puga <stas.puga@transoftgroup.com> Date: Fri, 26 Oct 2018 12:59:49 +0300 Subject: [PATCH 506/812] MAGETWO-95517: Add different types of products on the quote including gift card --- .../Mftf/ActionGroup/AdminProductAttributeActionGroup.xml | 1 - .../Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index c44610ef19649..80cadbb6571f2 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -13,7 +13,6 @@ <argument name="ProductAttribute"/> </arguments> <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> <fillField selector="{{AdminProductAttributeGridSection.FilterByAttributeCode}}" userInput="{{ProductAttribute.attribute_code}}" stepKey="setAttributeCode"/> <click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="searchForAttributeFromTheGrid"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml index c21f23d16463e..5be2a84f54555 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeOptionData.xml @@ -65,7 +65,7 @@ <data key="is_default">false</data> <data key="sort_order">0</data> </entity> - <entity name="productAttributeOption7" type="ProductAttributeOption"> + <entity name="ProductAttributeOption7" type="ProductAttributeOption"> <var key="attribute_code" entityKey="attribute_code" entityType="ProductAttribute"/> <data key="label" unique="suffix">Green</data> <data key="is_default">false</data> @@ -73,7 +73,7 @@ <requiredEntity type="StoreLabel">Option7Store0</requiredEntity> <requiredEntity type="StoreLabel">Option8Store1</requiredEntity> </entity> - <entity name="productAttributeOption8" type="ProductAttributeOption"> + <entity name="ProductAttributeOption8" type="ProductAttributeOption"> <var key="attribute_code" entityKey="attribute_code" entityType="ProductAttribute"/> <data key="label" unique="suffix">Red</data> <data key="is_default">false</data> From 4bed4727be909f0c57b6e7df402a84e545d913e9 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Fri, 26 Oct 2018 13:12:14 +0300 Subject: [PATCH 507/812] ENGCOM-3259: [Forwardport] 17516: added Australian states #18774. Fix static tests. --- .../Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php index e71abf3a58571..20306d08a292c 100644 --- a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForAustralia.php @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Directory\Setup\Patch\Data; use Magento\Directory\Setup\DataInstaller; From 63cc7536ae1d0a070c047b3b06ad3eb1889b61a7 Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh <nikita.shcherbatykh@transoftgroup.com> Date: Fri, 26 Oct 2018 13:22:57 +0300 Subject: [PATCH 508/812] MAGETWO-95753: [2.3] Cannot save product with Tier Prices --- app/code/Magento/Catalog/Helper/Data.php | 23 ++-- .../Backend/TierPrice/UpdateHandler.php | 17 ++- .../Controller/Adminhtml/ProductTest.php | 103 ++++++++++++++++++ 3 files changed, 125 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Catalog/Helper/Data.php b/app/code/Magento/Catalog/Helper/Data.php index ae20cda460796..c83eb70486c43 100644 --- a/app/code/Magento/Catalog/Helper/Data.php +++ b/app/code/Magento/Catalog/Helper/Data.php @@ -7,6 +7,7 @@ use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Store\Model\ScopeInterface; use Magento\Customer\Model\Session as CustomerSession; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Pricing\PriceCurrencyInterface; @@ -273,7 +274,8 @@ public function setStoreId($store) /** * Return current category path or get it from current category - * and creating array of categories|product paths for breadcrumbs + * + * Creating array of categories|product paths for breadcrumbs * * @return array */ @@ -382,6 +384,7 @@ public function getLastViewedUrl() /** * Split SKU of an item by dashes and spaces + * * Words will not be broken, unless this length is greater than $length * * @param string $sku @@ -410,14 +413,15 @@ public function getAttributeHiddenFields() /** * Retrieve Catalog Price Scope * - * @return int + * @return int/null */ - public function getPriceScope() + public function getPriceScope(): ?int { - return $this->scopeConfig->getValue( + $priceScope = $this->scopeConfig->getValue( self::XML_PATH_PRICE_SCOPE, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); + return isset($priceScope) ? (int)$priceScope : null; } /** @@ -439,7 +443,7 @@ public function isUsingStaticUrlsAllowed() { return $this->scopeConfig->isSetFlag( self::CONFIG_USE_STATIC_URLS, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ScopeInterface::SCOPE_STORE ); } @@ -454,7 +458,7 @@ public function isUrlDirectivesParsingAllowed() { return $this->scopeConfig->isSetFlag( self::CONFIG_PARSE_URL_DIRECTIVES, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $this->_storeId ); } @@ -472,6 +476,7 @@ public function getPageTemplateProcessor() /** * Whether to display items count for each filter option + * * @param int $storeId Store view ID * @return bool */ @@ -479,12 +484,14 @@ public function shouldDisplayProductCountOnLayer($storeId = null) { return $this->scopeConfig->isSetFlag( self::XML_PATH_DISPLAY_PRODUCT_COUNT, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + ScopeInterface::SCOPE_STORE, $storeId ); } /** + * Convert tax address array to address data object with country id and postcode + * * @param array $taxAddress * @return \Magento\Customer\Api\Data\AddressInterface|null */ diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php index b4d6dc2c19e51..aef3e87586015 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php @@ -86,10 +86,10 @@ public function execute($entity, $arguments = []) __('Tier prices data should be array, but actually other type is received') ); } - $websiteId = $this->storeManager->getStore($entity->getStoreId())->getWebsiteId(); + $websiteId = (int)$this->storeManager->getStore($entity->getStoreId())->getWebsiteId(); $isGlobal = $attribute->isScopeGlobal() || $websiteId === 0; $identifierField = $this->metadataPoll->getMetadata(ProductInterface::class)->getLinkField(); - $productId = (int) $entity->getData($identifierField); + $productId = (int)$entity->getData($identifierField); // prepare original data to compare $origPrices = []; @@ -98,7 +98,7 @@ public function execute($entity, $arguments = []) $origPrices = $entity->getOrigData($attribute->getName()); } - $old = $this->prepareOriginalDataToCompare($origPrices, $isGlobal); + $old = $this->prepareOldTierPriceToCompare($origPrices); // prepare data for save $new = $this->prepareNewDataForSave($priceRows, $isGlobal); @@ -271,21 +271,18 @@ private function isWebsiteGlobal(int $websiteId): bool } /** - * Prepare original data to compare. + * Prepare old data to compare. * * @param array|null $origPrices - * @param bool $isGlobal * @return array */ - private function prepareOriginalDataToCompare(?array $origPrices, bool $isGlobal = true): array + private function prepareOldTierPriceToCompare(?array $origPrices): array { $old = []; if (is_array($origPrices)) { foreach ($origPrices as $data) { - if ($isGlobal === $this->isWebsiteGlobal((int)$data['website_id'])) { - $key = $this->getPriceKey($data); - $old[$key] = $data; - } + $key = $this->getPriceKey($data); + $old[$key] = $data; } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php index 06bbc43e36e8d..d949993e7ea3c 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php @@ -252,4 +252,107 @@ public function saveActionWithAlreadyExistingUrlKeyDataProvider() ] ]; } + + /** + * Test product save with selected tier price + * + * @dataProvider saveActionTierPriceDataProvider + * @param array $postData + * @param array $tierPrice + * @magentoDataFixture Magento/Catalog/_files/product_has_tier_price_show_as_low_as.php + * @magentoAppIsolation enabled + * @magentoConfigFixture current_store catalog/price/scope 1 + * @magentoDbIsolation disabled + */ + public function testSaveActionTierPrice(array $postData, array $tierPrice) + { + $postData['product'] = $this->getProductData($tierPrice); + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue($postData); + $this->dispatch('backend/catalog/product/save/id/' . $postData['id']); + $this->assertSessionMessages( + $this->contains('You saved the product.'), + \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + ); + } + + /** + * Provide test data for testSaveActionWithAlreadyExistingUrlKey(). + * + * @return array + */ + public function saveActionTierPriceDataProvider() + { + return [ + [ + 'post_data' => [ + 'id' => '1', + 'type' => 'simple', + 'store' => '0', + 'set' => '4', + 'back' => 'edit', + 'product' => [], + 'is_downloadable' => '0', + 'affect_configurable_product_attributes' => '1', + 'new_variation_attribute_set_id' => '4', + 'use_default' => [ + 'gift_message_available' => '0', + 'gift_wrapping_available' => '0' + ], + 'configurable_matrix_serialized' => '[]', + 'associated_product_ids_serialized' => '[]' + ], + 'tier_price_for_request' => [ + [ + 'price_id' => '1', + 'website_id' => '0', + 'cust_group' => '32000', + 'price' => '111.00', + 'price_qty' => '100', + 'website_price' => '111.0000', + 'initialize' => 'true', + 'record_id' => '1', + 'value_type' => 'fixed' + ], + [ + 'price_id' => '2', + 'website_id' => '1', + 'cust_group' => '32000', + 'price' => '222.00', + 'price_qty' => '200', + 'website_price' => '111.0000', + 'initialize' => 'true', + 'record_id' => '2', + 'value_type' => 'fixed' + ], + [ + 'price_id' => '3', + 'website_id' => '1', + 'cust_group' => '32000', + 'price' => '333.00', + 'price_qty' => '300', + 'website_price' => '111.0000', + 'initialize' => 'true', + 'record_id' => '3', + 'value_type' => 'fixed' + ] + ] + ] + ]; + } + + /** + * Return product data for test without entity_id for further save + * + * @param array $tierPrice + * @return array + */ + private function getProductData(array $tierPrice) + { + $repository = $this->_objectManager->create(\Magento\Catalog\Model\ProductRepository::class); + $product = $repository->get('tier_prices')->getData(); + $product['tier_price'] = $tierPrice; + unset($product['entity_id']); + return $product; + } } From c8eb11567542d5e8002180801153fa19f6724336 Mon Sep 17 00:00:00 2001 From: David Verholen <david@verholen.com> Date: Fri, 26 Oct 2018 12:42:07 +0200 Subject: [PATCH 509/812] GraphQL-43: introduce wishlist graphql module --- .../WishlistItemsProductsResolver.php | 58 ++++++++++++++++++ .../Model/Resolver/WishlistItemsResolver.php | 60 +++++++++++++++++++ .../Model/Resolver/WishlistResolver.php | 55 +++++++++++++++++ .../Model/WishlistDataProvider.php | 39 ++++++++++++ .../Model/WishlistItemsDataProvider.php | 52 ++++++++++++++++ .../WishlistItemsProductDataProvider.php | 32 ++++++++++ app/code/Magento/WishlistGraphQl/README.md | 4 ++ .../Magento/WishlistGraphQl/composer.json | 25 ++++++++ .../Magento/WishlistGraphQl/etc/module.xml | 10 ++++ .../WishlistGraphQl/etc/schema.graphqls | 20 +++++++ .../Magento/WishlistGraphQl/registration.php | 9 +++ composer.json | 1 + 12 files changed, 365 insertions(+) create mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php create mode 100644 app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php create mode 100644 app/code/Magento/WishlistGraphQl/README.md create mode 100644 app/code/Magento/WishlistGraphQl/composer.json create mode 100644 app/code/Magento/WishlistGraphQl/etc/module.xml create mode 100644 app/code/Magento/WishlistGraphQl/etc/schema.graphqls create mode 100644 app/code/Magento/WishlistGraphQl/registration.php diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php new file mode 100644 index 0000000000000..567e85c3c0309 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php @@ -0,0 +1,58 @@ +<?php +declare(strict_types=1); +/** + * WishlistItemsProductsResolver + * + * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. + * @author david.verholen@brandung.de + */ + +namespace Magento\WishlistGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Framework\GraphQl\Query\Resolver\Value; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\WishlistGraphQl\Model\WishlistItemsProductDataProvider; + +class WishlistItemsProductsResolver implements ResolverInterface +{ + /** + * @var WishlistItemsProductDataProvider + */ + private $productDataProvider; + + public function __construct(WishlistItemsProductDataProvider $productDataProvider) + { + $this->productDataProvider = $productDataProvider; + } + + + /** + * Fetches the data from persistence models and format it according to the GraphQL schema. + * + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return mixed|Value + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['product_id'])) { + throw new GraphQlInputException( + __('Missing key %1 in wishlist item data', ['product_id']) + ); + } + return $this->productDataProvider->getProductDataById($value['product_id']); + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php new file mode 100644 index 0000000000000..3f51db6eef3e1 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php @@ -0,0 +1,60 @@ +<?php +declare(strict_types=1); +/** + * WishlistItemTypeResolver + * + * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. + * @author david.verholen@brandung.de + */ + +namespace Magento\WishlistGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Framework\GraphQl\Query\Resolver\Value; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Wishlist\Model\Item; +use Magento\WishlistGraphQl\Model\WishlistItemsDataProvider; + +class WishlistItemsResolver implements ResolverInterface +{ + /** + * @var WishlistItemsDataProvider + */ + private $wishlistItemsDataProvider; + + public function __construct(WishlistItemsDataProvider $wishlistItemsDataProvider) + { + $this->wishlistItemsDataProvider = $wishlistItemsDataProvider; + } + + /** + * Fetches the data from persistence models and format it according to the GraphQL schema. + * + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return mixed|Value + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + return array_map(function (Item $wishlistItem) { + return [ + 'id' => $wishlistItem->getId(), + 'qty' => $wishlistItem->getData('qty'), + 'description' => (string)$wishlistItem->getDescription(), + 'added_at' => $wishlistItem->getAddedAt(), + 'product_id' => (int)$wishlistItem->getProductId() + ]; + }, $this->wishlistItemsDataProvider->getWishlistItemsForCustomer($context->getUserId())); + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php new file mode 100644 index 0000000000000..3aec792b9de54 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php @@ -0,0 +1,55 @@ +<?php +declare(strict_types=1); +/** + * WishlistItemTypeResolver + * + * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. + * @author david.verholen@brandung.de + */ + +namespace Magento\WishlistGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Framework\GraphQl\Query\Resolver\Value; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\WishlistGraphQl\Model\WishlistDataProvider; + +class WishlistResolver implements ResolverInterface +{ + /** + * @var WishlistDataProvider + */ + private $wishlistDataProvider; + + public function __construct(WishlistDataProvider $wishlistDataProvider) + { + $this->wishlistDataProvider = $wishlistDataProvider; + } + + /** + * Fetches the data from persistence models and format it according to the GraphQL schema. + * + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return mixed|Value + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + $wishlist = $this->wishlistDataProvider->getWishlistForCustomer($context->getUserId()); + return [ + 'sharing_code' => $wishlist->getSharingCode(), + 'updated_at' => $wishlist->getUpdatedAt() + ]; + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php new file mode 100644 index 0000000000000..8f472d610ff4c --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php @@ -0,0 +1,39 @@ +<?php +declare(strict_types=1); +/** + * WishlistItemTypeResolver + * + * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. + * @author david.verholen@brandung.de + */ + +namespace Magento\WishlistGraphQl\Model; + +use Magento\Wishlist\Model\ResourceModel\Wishlist; +use Magento\Wishlist\Model\WishlistFactory; + +class WishlistDataProvider +{ + /** + * @var Wishlist + */ + private $wishlistResource; + /** + * @var WishlistFactory + */ + private $wishlistFactory; + + public function __construct(Wishlist $wishlistResource, WishlistFactory $wishlistFactory) + { + $this->wishlistResource = $wishlistResource; + $this->wishlistFactory = $wishlistFactory; + } + + public function getWishlistForCustomer(int $customerId): \Magento\Wishlist\Model\Wishlist + { + /** @var \Magento\Wishlist\Model\Wishlist $wishlist */ + $wishlist = $this->wishlistFactory->create(); + $this->wishlistResource->load($wishlist, $customerId, 'customer_id'); + return $wishlist; + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php new file mode 100644 index 0000000000000..e339b4886a942 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php @@ -0,0 +1,52 @@ +<?php +declare(strict_types=1); +/** + * WishlistItemTypeResolver + * + * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. + * @author david.verholen@brandung.de + */ + +namespace Magento\WishlistGraphQl\Model; + +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Wishlist\Model\Item; +use Magento\Wishlist\Model\ResourceModel\Item\CollectionFactory as WishlistItemCollectionFactory; + +class WishlistItemsDataProvider +{ + + /** + * @var WishlistItemCollectionFactory + */ + private $wishlistItemCollectionFactory; + /** + * @var StoreManagerInterface + */ + private $storeManager; + + public function __construct( + WishlistItemCollectionFactory $wishlistItemCollectionFactory, + StoreManagerInterface $storeManager + ) { + $this->wishlistItemCollectionFactory = $wishlistItemCollectionFactory; + $this->storeManager = $storeManager; + } + + /** + * @param int $customerId + * @return Item[] + */ + public function getWishlistItemsForCustomer(int $customerId): array + { + $wishlistItemCollection = $this->wishlistItemCollectionFactory->create(); + $wishlistItemCollection->addCustomerIdFilter($customerId); + $wishlistItemCollection->addStoreFilter(array_map(function (StoreInterface $store) { + return $store->getId(); + }, $this->storeManager->getStores())); + $wishlistItemCollection->setVisibilityFilter(); + $wishlistItemCollection->load(); + return $wishlistItemCollection->getItems(); + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php new file mode 100644 index 0000000000000..a9aa5dc184397 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php @@ -0,0 +1,32 @@ +<?php +declare(strict_types=1); +/** + * WishlistItemsProductsResolver + * + * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. + * @author david.verholen@brandung.de + */ + +namespace Magento\WishlistGraphQl\Model; + +use Magento\Catalog\Api\ProductRepositoryInterface; + +class WishlistItemsProductDataProvider +{ + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + public function __construct(ProductRepositoryInterface $productRepository) + { + $this->productRepository = $productRepository; + } + + public function getProductDataById(int $productId) { + $product = $this->productRepository->getById($productId); + $productData = $product->toArray(); + $productData['model'] = $product; + return $productData; + } +} diff --git a/app/code/Magento/WishlistGraphQl/README.md b/app/code/Magento/WishlistGraphQl/README.md new file mode 100644 index 0000000000000..9121593e6a759 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/README.md @@ -0,0 +1,4 @@ +# WishlistGraphQl + +**WishlistGraphQl** provides type information for the GraphQl module +to generate wishlist fields. diff --git a/app/code/Magento/WishlistGraphQl/composer.json b/app/code/Magento/WishlistGraphQl/composer.json new file mode 100644 index 0000000000000..2be27d4239f73 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/composer.json @@ -0,0 +1,25 @@ +{ + "name": "magento/module-wishlist-graph-ql", + "description": "N/A", + "type": "magento2-module", + "require": { + "php": "~7.1.3||~7.2.0", + "magento/framework": "*", + "magento/module-catalog": "*" + }, + "suggest": { + "magento/module-wishlist": "*" + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\WishlistGraphQl\\": "" + } + } +} diff --git a/app/code/Magento/WishlistGraphQl/etc/module.xml b/app/code/Magento/WishlistGraphQl/etc/module.xml new file mode 100644 index 0000000000000..337623cc85a92 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/etc/module.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:Module/etc/module.xsd"> + <module name="Magento_WishlistGraphQl" /> +</config> diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls new file mode 100644 index 0000000000000..5c6d701138560 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -0,0 +1,20 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +type Query { + wishlist: WishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistResolver") @doc(description: "todo") +} + +type WishlistOutput { + items: [WishlistItem] @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsResolver") @doc(description: "todo"), + sharing_code: String! @doc(description: "todo"), + updated_at: String! @doc(description: "todo") +} + +type WishlistItem { + id: Int! @doc(description: "todo") + qty: Float! @doc(description: "todo"), + description: String! @doc(description: "todo"), + added_at: String! @doc(description: "todo"), + product: ProductInterface @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsProductsResolver") +} \ No newline at end of file diff --git a/app/code/Magento/WishlistGraphQl/registration.php b/app/code/Magento/WishlistGraphQl/registration.php new file mode 100644 index 0000000000000..f2047f225e5b6 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/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_WishlistGraphQl', __DIR__); diff --git a/composer.json b/composer.json index 3f8f0a033c893..eede85d273777 100644 --- a/composer.json +++ b/composer.json @@ -237,6 +237,7 @@ "magento/module-weee": "*", "magento/module-widget": "*", "magento/module-wishlist": "*", + "magento/module-wishlist-graph-ql": "*", "magento/module-wishlist-analytics": "*", "magento/theme-adminhtml-backend": "*", "magento/theme-frontend-blank": "*", From 0286f170c6e4c74d2e68a11c3de5f588710143fe Mon Sep 17 00:00:00 2001 From: David Verholen <david@verholen.com> Date: Fri, 26 Oct 2018 13:35:10 +0200 Subject: [PATCH 510/812] GraphQL-43: add missing hard dependencies --- app/code/Magento/WishlistGraphQl/composer.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/composer.json b/app/code/Magento/WishlistGraphQl/composer.json index 2be27d4239f73..9226ea1754e6a 100644 --- a/app/code/Magento/WishlistGraphQl/composer.json +++ b/app/code/Magento/WishlistGraphQl/composer.json @@ -5,10 +5,9 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/framework": "*", - "magento/module-catalog": "*" - }, - "suggest": { - "magento/module-wishlist": "*" + "magento/module-catalog": "*", + "magento/module-wishlist": "*", + "magento/module-store": "*" }, "license": [ "OSL-3.0", From 98715ca4060c262d90f48e31c1f1d202bd2d23b5 Mon Sep 17 00:00:00 2001 From: stani <sa@webvisum.de> Date: Fri, 26 Oct 2018 13:16:58 +0200 Subject: [PATCH 511/812] magento-engcom/import-export-improvements#93: show errors and link to download csv error report on success page --- .../Controller/Adminhtml/Import/Start.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index 8f64d023c19f9..06b69c512a194 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -93,6 +93,20 @@ public function execute() $this->addErrorMessages($resultBlock, $errorAggregator); } else { $this->importModel->invalidateIndex(); + + $noticeHtml = $this->historyModel->getSummary(); + + if($this->historyModel->getErrorFile()) { + $noticeHtml .= '<div class="import-error-wrapper">' . __('Only the first 100 errors are shown. ') + . '<a href="' + . $this->createDownloadUrlImportHistoryFile($this->historyModel->getErrorFile()) + . '">' . __('Download full report') . '</a></div>'; + } + + $resultBlock->addNotice( + $noticeHtml + ); + $this->addErrorMessages($resultBlock, $errorAggregator); $resultBlock->addSuccess(__('Import successfully done')); } From 2e4ea72289c28a223354b18b399e28843267e538 Mon Sep 17 00:00:00 2001 From: David Verholen <david@verholen.com> Date: Fri, 26 Oct 2018 14:14:25 +0200 Subject: [PATCH 512/812] GraphQL-43: add test to retrieve wishlist --- .../Magento/GraphQl/Wishlist/WishlistTest.php | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php new file mode 100644 index 0000000000000..53577d02df50f --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Wishlist; + +use Magento\Integration\Api\CustomerTokenServiceInterface; +use Magento\TestFramework\TestCase\GraphQlAbstract; +use Magento\Wishlist\Model\Item; + +class WishlistTest extends GraphQlAbstract +{ + /** + * @var \Magento\TestFramework\ObjectManager + */ + private $objectManager; + /** + * @var CustomerTokenServiceInterface + */ + private $customerTokenService; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->customerTokenService = $this->objectManager->get(CustomerTokenServiceInterface::class); + } + + /** + * Verify the fields of CMS Block selected by identifiers + * + * @magentoApiDataFixture Magento/Wishlist/_files/wishlist.php + * @throws \Magento\Framework\Exception\AuthenticationException + * @throws \Exception + */ + public function testGetCustomersWishlist(): void + { + /** @var \Magento\Wishlist\Model\Wishlist $wishlist */ + $wishlist = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Wishlist\Model\Wishlist::class + ); + $wishlist->loadByCustomerId(1, true); + /** @var Item $wishlistItem */ + $wishlistItem = $wishlist->getItemCollection()->getFirstItem(); + $wishlistItemProduct = $wishlistItem->getProduct(); + $query = + <<<QUERY +{ + wishlist { + items { + id + qty + product { + sku + name + } + description + added_at + } + sharing_code + updated_at + } +} +QUERY; + + $response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders('customer@example.com', 'password')); + $this->assertEquals($wishlist->getSharingCode(), $response['wishlist']['sharing_code']); + $this->assertEquals($wishlistItem->getData('qty'), $response['wishlist']['items'][0]['qty']); + $this->assertEquals($wishlistItem->getDescription(), $response['wishlist']['items'][0]['description']); + $this->assertEquals($wishlistItemProduct->getSku(), $response['wishlist']['items'][0]['product']['sku']); + $this->assertEquals($wishlistItemProduct->getName(), $response['wishlist']['items'][0]['product']['name']); + } + + /** + * @param string $email + * @param string $password + * @return array + * @throws \Magento\Framework\Exception\AuthenticationException + */ + private function getCustomerAuthHeaders(string $email, string $password): array + { + $customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password); + return ['Authorization' => 'Bearer ' . $customerToken]; + } +} From 89eb2776be3bdacf84a86367d866b8746452f129 Mon Sep 17 00:00:00 2001 From: David Verholen <david@verholen.com> Date: Fri, 26 Oct 2018 14:19:15 +0200 Subject: [PATCH 513/812] GraphQL-43: use correct copyright headers in introduced php classes --- .../Model/Resolver/WishlistItemsProductsResolver.php | 8 +++----- .../Model/Resolver/WishlistItemsResolver.php | 8 +++----- .../WishlistGraphQl/Model/Resolver/WishlistResolver.php | 8 +++----- .../WishlistGraphQl/Model/WishlistDataProvider.php | 8 +++----- .../WishlistGraphQl/Model/WishlistItemsDataProvider.php | 8 +++----- .../Model/WishlistItemsProductDataProvider.php | 8 +++----- 6 files changed, 18 insertions(+), 30 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php index 567e85c3c0309..26ace0e849e3f 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php @@ -1,11 +1,9 @@ <?php -declare(strict_types=1); /** - * WishlistItemsProductsResolver - * - * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. - * @author david.verholen@brandung.de + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\WishlistGraphQl\Model\Resolver; diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php index 3f51db6eef3e1..707618b10602d 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php @@ -1,11 +1,9 @@ <?php -declare(strict_types=1); /** - * WishlistItemTypeResolver - * - * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. - * @author david.verholen@brandung.de + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\WishlistGraphQl\Model\Resolver; diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php index 3aec792b9de54..ba1a6e935c10e 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php @@ -1,11 +1,9 @@ <?php -declare(strict_types=1); /** - * WishlistItemTypeResolver - * - * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. - * @author david.verholen@brandung.de + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\WishlistGraphQl\Model\Resolver; diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php index 8f472d610ff4c..a62ddebd91120 100644 --- a/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php +++ b/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php @@ -1,11 +1,9 @@ <?php -declare(strict_types=1); /** - * WishlistItemTypeResolver - * - * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. - * @author david.verholen@brandung.de + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\WishlistGraphQl\Model; diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php index e339b4886a942..ca87b23460fc7 100644 --- a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php +++ b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php @@ -1,11 +1,9 @@ <?php -declare(strict_types=1); /** - * WishlistItemTypeResolver - * - * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. - * @author david.verholen@brandung.de + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\WishlistGraphQl\Model; diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php index a9aa5dc184397..76df065a80702 100644 --- a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php +++ b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php @@ -1,11 +1,9 @@ <?php -declare(strict_types=1); /** - * WishlistItemsProductsResolver - * - * @copyright Copyright © 2018 brandung GmbH & Co. KG. All rights reserved. - * @author david.verholen@brandung.de + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\WishlistGraphQl\Model; From 7db2cc9fbac6adc17e43be576aa149b7e7965b8a Mon Sep 17 00:00:00 2001 From: rahul <rahul@webkul.com> Date: Fri, 26 Oct 2018 17:50:12 +0530 Subject: [PATCH 514/812] fixed Translation issue send-friend in send.phtml --- app/code/Magento/SendFriend/view/frontend/templates/send.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml index 862ef5fdebc3c..4922a9f365ced 100644 --- a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml +++ b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml @@ -17,7 +17,7 @@ <div class="secondary"> <button type="button" id="btn-remove<%- data._index_ %>" class="action remove" title="<?= $block->escapeHtmlAttr(__('Remove Recipent')) ?>"> - <span><?= $block->escapeJs($block->escapeHtml(__('Remove'))) ?></span> + <span><?= $block->escapeHtml(__('Remove')) ?></span> </button> </div> </div> From e5e58325500ef7d6df7dd7d928f25a33962f9d69 Mon Sep 17 00:00:00 2001 From: stani <sa@webvisum.de> Date: Fri, 26 Oct 2018 14:42:26 +0200 Subject: [PATCH 515/812] magento-engcom/import-export-improvements#54: function getBehavior extended with BEHAVIOUR_ADD_UPDATE and BEHAVIOR_CUSTOM --- .../Magento/ImportExport/Model/Import/Entity/AbstractEntity.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php index e965e8ad207fd..74e2c5626236c 100644 --- a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php +++ b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php @@ -554,7 +554,9 @@ public function getBehavior() $this->_parameters['behavior'] ) || $this->_parameters['behavior'] != ImportExport::BEHAVIOR_APPEND && + $this->_parameters['behavior'] != ImportExport::BEHAVIOR_ADD_UPDATE && $this->_parameters['behavior'] != ImportExport::BEHAVIOR_REPLACE && + $this->_parameters['behavior'] != ImportExport::BEHAVIOR_CUSTOM && $this->_parameters['behavior'] != ImportExport::BEHAVIOR_DELETE ) { return ImportExport::getDefaultBehavior(); From 3f5bcdd911b1d7b9604362f078bcfd9b7baa9d3f Mon Sep 17 00:00:00 2001 From: matt <matt@dforce3000.de> Date: Fri, 26 Oct 2018 15:01:27 +0200 Subject: [PATCH 516/812] magento2#222 Apply changes from CR for PR 162 --- .../Model/Customer/UpdateAccountInformation.php | 2 +- .../Model/Resolver/ChangePassword.php | 6 +++--- .../Model/Resolver/GenerateCustomerToken.php | 4 ++-- .../Model/Resolver/RevokeCustomerToken.php | 2 +- app/code/Magento/CustomerGraphQl/etc/schema.graphqls | 12 ++++++++---- .../Exception/GraphQlAlreadyExistsException.php | 2 +- .../Exception/GraphQlAuthenticationException.php | 2 +- .../Exception/GraphQlAuthorizationException.php | 2 +- .../Exception/GraphQlNoSuchEntityException.php | 2 +- 9 files changed, 19 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/UpdateAccountInformation.php b/app/code/Magento/CustomerGraphQl/Model/Customer/UpdateAccountInformation.php index d235d51b5e52d..36365f1910f27 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/UpdateAccountInformation.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/UpdateAccountInformation.php @@ -73,7 +73,7 @@ public function execute(int $customerId, array $data): void if (isset($data['email']) && $customer->getEmail() !== $data['email']) { if (!isset($data['password']) || empty($data['password'])) { - throw new GraphQlInputException(__('For changing "email" you should provide current "password".')); + throw new GraphQlInputException(__('Provide the current "password" to change "email".')); } $this->checkCustomerPassword->execute($data['password'], $customerId); diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/ChangePassword.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/ChangePassword.php index 98b0975b37169..78fa852a7ac59 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/ChangePassword.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/ChangePassword.php @@ -17,7 +17,7 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; /** - * @inheritdoc + * Change customer password resolver */ class ChangePassword implements ResolverInterface { @@ -70,11 +70,11 @@ public function resolve( array $args = null ) { if (!isset($args['currentPassword'])) { - throw new GraphQlInputException(__('"currentPassword" value should be specified')); + throw new GraphQlInputException(__('Specify the "currentPassword" value.')); } if (!isset($args['newPassword'])) { - throw new GraphQlInputException(__('"newPassword" value should be specified')); + throw new GraphQlInputException(__('Specify the "newPassword" value.')); } $currentUserId = $context->getUserId(); diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/GenerateCustomerToken.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/GenerateCustomerToken.php index 9719d048f606b..1bd77fe1cde8f 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/GenerateCustomerToken.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/GenerateCustomerToken.php @@ -45,11 +45,11 @@ public function resolve( array $args = null ) { if (!isset($args['email'])) { - throw new GraphQlInputException(__('"email" value should be specified')); + throw new GraphQlInputException(__('Specify the "email" value.')); } if (!isset($args['password'])) { - throw new GraphQlInputException(__('"password" value should be specified')); + throw new GraphQlInputException(__('Specify the "password" value.')); } try { diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/RevokeCustomerToken.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/RevokeCustomerToken.php index d3b16c05a6492..3301162dc0088 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/RevokeCustomerToken.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/RevokeCustomerToken.php @@ -55,6 +55,6 @@ public function resolve( $this->checkCustomerAccount->execute($currentUserId, $currentUserType); - return $this->customerTokenService->revokeCustomerAccessToken((int)$currentUserId); + return ['result' => $this->customerTokenService->revokeCustomerAccessToken((int)$currentUserId)]; } } diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls index b8411f00c5cb1..ca4ac6cc245a7 100644 --- a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls @@ -6,10 +6,10 @@ type Query { } type Mutation { - generateCustomerToken(email: String!, password: String!): CustomerToken @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\GenerateCustomerToken") @doc(description:"Retrieve Customer token") - changeCustomerPassword(currentPassword: String!, newPassword: String!): Customer @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\ChangePassword") @doc(description:"Changes password for logged in customer") - updateCustomer (input: UpdateCustomerInput): UpdateCustomerOutput @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\UpdateCustomer") @doc(description:"Update customer personal information") - revokeCustomerToken: Boolean @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\RevokeCustomerToken") @doc(description:"Revoke Customer token") + generateCustomerToken(email: String!, password: String!): CustomerToken @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\GenerateCustomerToken") @doc(description:"Retrieve the customer token") + changeCustomerPassword(currentPassword: String!, newPassword: String!): Customer @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\ChangePassword") @doc(description:"Changes the password for the logged-in customer") + updateCustomer (input: UpdateCustomerInput!): UpdateCustomerOutput @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\UpdateCustomer") @doc(description:"Update the customer's personal information") + revokeCustomerToken: RevokeCustomerTokenOutput @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\RevokeCustomerToken") @doc(description:"Revoke the customer token") } type CustomerToken { @@ -28,6 +28,10 @@ type UpdateCustomerOutput { customer: Customer! } +type RevokeCustomerTokenOutput { + result: Boolean! +} + type Customer @doc(description: "Customer defines the customer name and address and other details") { created_at: String @doc(description: "Timestamp indicating when the account was created") group_id: Int @doc(description: "The group assigned to the user. Default values are 0 (Not logged in), 1 (General), 2 (Wholesale), and 3 (Retailer)") diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAlreadyExistsException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAlreadyExistsException.php index d25707b2ca347..8275219e9e554 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAlreadyExistsException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAlreadyExistsException.php @@ -12,7 +12,7 @@ use Magento\Framework\Phrase; /** - * Class GraphQlAlreadyExistsException + * Exception for GraphQL to be thrown when data already exists */ class GraphQlAlreadyExistsException extends AlreadyExistsException implements ClientAware { diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthenticationException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthenticationException.php index 4df74bbf332cd..44c3d07bd186f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthenticationException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthenticationException.php @@ -12,7 +12,7 @@ use Magento\Framework\Phrase; /** - * Class GraphQlAuthenticationException + * Exception for GraphQL to be thrown when authentication fails */ class GraphQlAuthenticationException extends AuthenticationException implements ClientAware { diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php index 5b76e0ab9f5ae..f71652edc63b3 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php @@ -11,7 +11,7 @@ use Magento\Framework\Exception\AuthorizationException; /** - * Class GraphQlAuthorizationException + * Exception for GraphQL to be thrown when authorization fails */ class GraphQlAuthorizationException extends AuthorizationException implements \GraphQL\Error\ClientAware { diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php index 05c5925e8d1e5..4bd24d6cfd4a7 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php @@ -11,7 +11,7 @@ use Magento\Framework\Phrase; /** - * Class GraphQlNoSuchEntityException + * Exception for GraphQL to be thrown when entity does not exists */ class GraphQlNoSuchEntityException extends NoSuchEntityException implements \GraphQL\Error\ClientAware { From dfc9cd0a5ce6d9285b56b40f9cc4c429f8d5f33c Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 26 Oct 2018 17:23:09 +0300 Subject: [PATCH 517/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml index b10c8e5ad54a0..1cd0e15780c11 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml @@ -161,7 +161,7 @@ <!-- Go to the product page and see the uploaded image --> <amOnPage url="$$secondProduct.name$$.html" stepKey="goToStorefront2"/> <waitForPageLoad stepKey="waitForStorefront2"/> - <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('Large')}}" stepKey="seeLarge2"/> + <seeElementInDOM selector="{{StorefrontProductMediaSection.imageFile('large')}}" stepKey="seeLarge2"/> </test> <test name="AdminSimpleProductRemoveImagesTest"> From 505ac52e2a242555873545faced2eef0a275fe4e Mon Sep 17 00:00:00 2001 From: Tobias Maile <tobias.maile@brandung.de> Date: Fri, 26 Oct 2018 16:55:02 +0200 Subject: [PATCH 518/812] GraphQL-202: [Mutations] adds sendEmailFriend Logic --- .../Model/Resolver/SendEmailToFriend.php | 147 ++++++++++++++++++ .../Magento/SendFriendGraphQl/etc/module.xml | 11 ++ .../SendFriendGraphQl/etc/schema.graphqls | 33 ++++ .../SendFriendGraphQl/registration.php | 9 ++ 4 files changed, 200 insertions(+) create mode 100644 app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php create mode 100644 app/code/Magento/SendFriendGraphQl/etc/module.xml create mode 100644 app/code/Magento/SendFriendGraphQl/etc/schema.graphqls create mode 100644 app/code/Magento/SendFriendGraphQl/registration.php diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php new file mode 100644 index 0000000000000..56f6d20b20f18 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -0,0 +1,147 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\SendFriendGraphQl\Model\Resolver; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\DataObjectFactory; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\SendFriend\Model\SendFriend; + +class SendEmailToFriend implements ResolverInterface +{ + /** + * @var SendFriend + */ + private $sendFriend; + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + /** + * @var DataObjectFactory + */ + private $dataObjectFactory; + + public function __construct( + SendFriend $sendFriend, + ProductRepositoryInterface $productRepository, + DataObjectFactory $dataObjectFactory + ) { + $this->sendFriend = $sendFriend; + $this->productRepository = $productRepository; + $this->dataObjectFactory = $dataObjectFactory; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + if ($this->sendFriend->getMaxSendsToFriend() && $this->sendFriend->isExceedLimit()) { + throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', + $this->sendFriend->getMaxSendsToFriend() + )); + } + + $product = $this->getProductFromRepository($args['input']['params']['product_id']); + $senderArray = $this->getSenderArrayFromArgs($args); + $recipientsArray = $this->getRecipientsArray($args); + //@todo clarify if event should be dispatched + //$this->_eventManager->dispatch('sendfriend_product', ['product' => $product]); + $this->sendFriend->setSender($senderArray); + $this->sendFriend->setRecipients($recipientsArray); + $this->sendFriend->setProduct($product); + + $this->prepareDataForValidation($args, $recipientsArray); + $validationResult = $this->sendFriend->validate(); + $this->addRecipientNameValidation($args); + if ($validationResult !== true) { + throw new GraphQlInputException(__(implode($validationResult))); + } + + $this->sendFriend->send(); + + return array_merge($senderArray, $recipientsArray); + } + + private function prepareDataForValidation(array $args, array $recipientsArray): void + { + $sender = $this->dataObjectFactory->create()->setData([ + 'name' => $args['input']['sender']['name'], + 'email'=> $args['input']['sender']['email'], + 'message' => $args['input']['sender']['message'], + ]); + $emails = []; + foreach ($recipientsArray['recipients'] as $recipient) { + $emails[] = $recipient['email']; + } + $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + + $this->sendFriend->setData('_sender', $sender); + $this->sendFriend->setData('_recipients', $recipients); + } + + /** + * @param array $args + * @throws GraphQlInputException + */ + private function addRecipientNameValidation(array $args): void + { + foreach ($args['input']['recipients'] as $recipient) { + if (empty($recipient['name'])) { + throw new GraphQlInputException( + __('Please Provide Name for Recipient with this Email Address: ' . $recipient['email'] + )); + } + } + } + + /** + * @param int $productId + * @return bool|\Magento\Catalog\Api\Data\ProductInterface + */ + private function getProductFromRepository(int $productId) + { + try { + $product = $this->productRepository->getById($productId); + if (!$product->isVisibleInCatalog()) { + return false; + } + } catch (NoSuchEntityException $noEntityException) { + return false; + } + + return $product; + } + + private function getRecipientsArray(array $args): array + { + $recipientsArray = []; + foreach ($args['input']['recipients'] as $recipient) { + $recipientsArray[] = [ + 'name' => $recipient['name'], + 'email' => $recipient['email'], + ]; + } + return ['recipients' => $recipientsArray]; + } + + private function getSenderArrayFromArgs(array $args): array + { + return ['sender' => [ + 'name' => $args['input']['sender']['name'], + 'email' => $args['input']['sender']['email'], + 'message' => $args['input']['sender']['message'], + ] + ]; + } +} diff --git a/app/code/Magento/SendFriendGraphQl/etc/module.xml b/app/code/Magento/SendFriendGraphQl/etc/module.xml new file mode 100644 index 0000000000000..14d792198cd5f --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/etc/module.xml @@ -0,0 +1,11 @@ +<?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_SendFriendGraphGl"/> +</config> diff --git a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls new file mode 100644 index 0000000000000..87bf90fd10072 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls @@ -0,0 +1,33 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +type Mutation { + sendEmailToFriend (input: SendEmailToFriendSenderInput): SendEmailToFriendOutput @resolver(class: "\\Magento\\SendFriendGraphQl\\Model\\Resolver\\SendEmailToFriend") @doc(description:"@todo") +} + +input SendEmailToFriendSenderInput { + sender: Sender! + params: Params! + recipients: [Recipient] +} + +type Sender { + name: String! + email: String! + message: String! +} +#@todo Prams can be removed if dispatching of event in app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php not needed +type Params { + product_id: Int! +} + +type Recipient { + name: String! + email: String! +} + + +type SendEmailToFriendOutput { + sender: Sender + recipients: [Recipient] +} diff --git a/app/code/Magento/SendFriendGraphQl/registration.php b/app/code/Magento/SendFriendGraphQl/registration.php new file mode 100644 index 0000000000000..c41607a0dc864 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/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_SendFriendGraphGl', __DIR__); From 9a7fa4c650dd41151d986486a02dd58d4c6cc2ff Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Fri, 26 Oct 2018 12:26:08 -0400 Subject: [PATCH 519/812] Added $_regionCollection property to class --- .../Magento/CustomerImportExport/Model/Import/Address.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/CustomerImportExport/Model/Import/Address.php b/app/code/Magento/CustomerImportExport/Model/Import/Address.php index e1345edcf146d..9ba50738ebc1a 100644 --- a/app/code/Magento/CustomerImportExport/Model/Import/Address.php +++ b/app/code/Magento/CustomerImportExport/Model/Import/Address.php @@ -101,6 +101,13 @@ class Address extends AbstractCustomer */ protected $_entityTable; + /** + * Region collection instance + * + * @var string + */ + protected $_regionCollection; + /** * Countries and regions * From 06a47b55f36dda9bec631eede0f4cf9566971b82 Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Fri, 26 Oct 2018 13:01:39 -0400 Subject: [PATCH 520/812] Added $websiteString property to test class --- .../Model/Import/AdvancedPricing/Validator/WebsiteTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php index b46e286e75007..41ac72bd8dacc 100644 --- a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php +++ b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php @@ -25,6 +25,11 @@ class WebsiteTest extends \PHPUnit\Framework\TestCase */ protected $website; + /** + * @var \Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator\Website|\PHPUnit_Framework_MockObject_MockObject + */ + protected $websiteString; + protected function setUp() { $this->webSiteModel = $this->getMockBuilder(\Magento\Store\Model\Website::class) From e3df0f684ac20c478685cc601590e5231a531eb1 Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Fri, 26 Oct 2018 13:12:37 -0400 Subject: [PATCH 521/812] Fixed miss called property in getStoreIdByCode method --- .../BundleImportExport/Model/Import/Product/Type/Bundle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php b/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php index 3ed7e144ddd5a..77d331a8b5696 100644 --- a/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php +++ b/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php @@ -779,7 +779,7 @@ protected function clear() */ private function getStoreIdByCode(string $storeCode): int { - if (!isset($this->storeIdToCode[$storeCode])) { + if (!isset($this->storeCodeToId[$storeCode])) { /** @var $store \Magento\Store\Model\Store */ foreach ($this->storeManager->getStores() as $store) { $this->storeCodeToId[$store->getCode()] = $store->getId(); From dfa2f25534e05050fde25d2b4b960f5ecfa173bd Mon Sep 17 00:00:00 2001 From: Rus0 <andoni@space.bar> Date: Fri, 26 Oct 2018 14:50:55 -0500 Subject: [PATCH 522/812] Resolves issue 6731 by adding a custom message for refunding shipping --- .../Sales/Model/Order/Creditmemo/Total/Discount.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php index 0cc4143e569db..c62f6459a5e91 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php @@ -10,6 +10,7 @@ class Discount extends AbstractTotal /** * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo * @return $this + * @throws \Magento\Framework\Exception\LocalizedException */ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) { @@ -26,6 +27,16 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) * basing on how much shipping should be refunded. */ $baseShippingAmount = $this->getBaseShippingAmount($creditmemo); + + /** + * If credit memo's shipping amount is set and Order's shipping amount is 0, + * throw exception with differente message + */ + if ( $baseShippingAmount && $order->getBaseShippingAmount() <= 0 ) { + throw new \Magento\Framework\Exception\LocalizedException( + new \Magento\Framework\Phrase("You can not refund shipping if there is no shipping amount.",[]) + ); + } if ($baseShippingAmount) { $baseShippingDiscount = $baseShippingAmount * $order->getBaseShippingDiscountAmount() / From 0f0f64de5c2ece4a0d3ec9ed54f65df3c30284e9 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <korshenk@adobe.com> Date: Fri, 26 Oct 2018 15:34:08 -0500 Subject: [PATCH 523/812] magento/magento2#18840: Invalid Unit Test Annotations - fixed invalid unit tests annotations that assert exception messages --- .../Unit/Model/Product/Gallery/GalleryManagementTest.php | 2 +- .../Catalog/Test/Unit/Model/Product/PriceModifierTest.php | 6 +++--- .../Test/Unit/Model/Product/TierPriceManagementTest.php | 2 +- app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php | 2 +- .../Downloadable/Test/Unit/Helper/DownloadTest.php | 2 +- .../GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php | 8 ++++---- .../GuestCartManagement/Plugin/AuthorizationTest.php | 2 +- .../Quote/Test/Unit/Model/Quote/Item/UpdaterTest.php | 2 +- .../Test/Unit/Model/ShippingAddressManagementTest.php | 2 +- .../Search/Test/Unit/Model/SynonymGroupRepositoryTest.php | 4 ++-- .../Theme/Test/Unit/Model/Theme/Source/ThemeTest.php | 1 - .../Ui/Test/Unit/Component/Filters/FilterModifierTest.php | 5 +++-- .../Magento/Framework/App/Test/Unit/ErrorHandlerTest.php | 4 ++-- .../App/Test/Unit/Response/Http/FileFactoryTest.php | 2 +- lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php | 2 +- .../Profiler/Test/Unit/Driver/Standard/StatTest.php | 4 ++-- .../Setup/Test/Unit/Module/I18n/Parser/ParserTest.php | 2 +- 17 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/GalleryManagementTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/GalleryManagementTest.php index 9fafbc9d9675b..1d12645019d1e 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/GalleryManagementTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Gallery/GalleryManagementTest.php @@ -266,7 +266,7 @@ public function testGetWithNonExistingProduct() /** * @expectedException \Magento\Framework\Exception\NoSuchEntityException - * @expectedExceptionText The image doesn't exist. Verify and try again. + * @expectedExceptionMessage The image doesn't exist. Verify and try again. */ public function testGetWithNonExistingImage() { diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/PriceModifierTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/PriceModifierTest.php index 754d80302d410..6029a2b820086 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/PriceModifierTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/PriceModifierTest.php @@ -54,7 +54,7 @@ protected function setUp() /** * @expectedException \Magento\Framework\Exception\NoSuchEntityException - * @expectedMessage Tier price is unavailable for this product. + * @expectedExceptionMessage Product hasn't group price with such data: customerGroupId = '1', website = 1, qty = 3 */ public function testRemoveWhenTierPricesNotExists() { @@ -70,7 +70,7 @@ public function testRemoveWhenTierPricesNotExists() /** * @expectedException \Magento\Framework\Exception\NoSuchEntityException - * @expectedMessage For current customerGroupId = '10' with 'qty' = 15 any tier price exist'. + * @expectedExceptionMessage Product hasn't group price with such data: customerGroupId = '10', website = 1, qty = 5 */ public function testRemoveTierPriceForNonExistingCustomerGroup() { @@ -81,7 +81,7 @@ public function testRemoveTierPriceForNonExistingCustomerGroup() ->will($this->returnValue($this->prices)); $this->productMock->expects($this->never())->method('setData'); $this->productRepositoryMock->expects($this->never())->method('save'); - $this->priceModifier->removeTierPrice($this->productMock, 10, 15, 1); + $this->priceModifier->removeTierPrice($this->productMock, 10, 5, 1); } public function testSuccessfullyRemoveTierPriceSpecifiedForAllGroups() diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/TierPriceManagementTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/TierPriceManagementTest.php index f340d0b204b62..ae479a9b34d48 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/TierPriceManagementTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/TierPriceManagementTest.php @@ -195,7 +195,7 @@ public function testSuccessDeleteTierPrice() /** * @expectedException \Magento\Framework\Exception\NoSuchEntityException - * @message The product doesn't exist. Verify and try again. + * @expectedExceptionMessage No such entity. */ public function testDeleteTierPriceFromNonExistingProduct() { diff --git a/app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php b/app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php index a196b10478c7f..ff7340f87f32e 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php @@ -98,7 +98,7 @@ public function testCheckQuoteItem() /** * @expectedException \Magento\Framework\Exception\LocalizedException - * @exceptedExceptionMessage The quote item isn't found. Verify the item and try again. + * @expectedExceptionMessage The quote item isn't found. Verify the item and try again. */ public function testCheckQuoteItemWithException() { diff --git a/app/code/Magento/Downloadable/Test/Unit/Helper/DownloadTest.php b/app/code/Magento/Downloadable/Test/Unit/Helper/DownloadTest.php index 7cb5b03b0385f..9551cfe982bd5 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Helper/DownloadTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Helper/DownloadTest.php @@ -89,7 +89,7 @@ public function testSetResourceInvalidPath() /** * @expectedException \Magento\Framework\Exception\LocalizedException - * @exectedExceptionMessage Please set resource file and link type. + * @expectedExceptionMessage Please set resource file and link type. */ public function testGetFileSizeNoResource() { diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php index 2170864407ea4..f3e060ad5fc72 100644 --- a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php +++ b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/OrderSaveTest.php @@ -128,7 +128,7 @@ public function testAfterSaveGiftMessages() /** * @expectedException \Magento\Framework\Exception\CouldNotSaveException - * @expectedMessage The gift message couldn't be added to the "Test message" order. + * @expectedExceptionMessage The gift message couldn't be added to the "Test message" order. */ public function testAfterSaveIfGiftMessagesNotExist() { @@ -146,7 +146,7 @@ public function testAfterSaveIfGiftMessagesNotExist() $this->giftMessageOrderRepositoryMock ->expects($this->once()) ->method('save') - ->willThrowException(new \Exception('TestMessage')); + ->willThrowException(new \Exception('Test message')); // save Gift Messages on item level $this->orderMock->expects($this->never())->method('getItems'); @@ -155,7 +155,7 @@ public function testAfterSaveIfGiftMessagesNotExist() /** * @expectedException \Magento\Framework\Exception\CouldNotSaveException - * @expectedMessage The gift message couldn't be added to the "Test message" order. + * @expectedExceptionMessage The gift message couldn't be added to the "Test message" order item. */ public function testAfterSaveIfItemGiftMessagesNotExist() { @@ -185,7 +185,7 @@ public function testAfterSaveIfItemGiftMessagesNotExist() $this->giftMessageOrderItemRepositoryMock ->expects($this->once())->method('save') ->with($orderId, $orderItemId, $this->giftMessageMock) - ->willThrowException(new \Exception('TestMessage')); + ->willThrowException(new \Exception('Test message')); $this->plugin->afterSave($this->orderRepositoryMock, $this->orderMock); } } diff --git a/app/code/Magento/Quote/Test/Unit/Model/GuestCartManagement/Plugin/AuthorizationTest.php b/app/code/Magento/Quote/Test/Unit/Model/GuestCartManagement/Plugin/AuthorizationTest.php index 22962aacc8dac..49ed8a10bee35 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/GuestCartManagement/Plugin/AuthorizationTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/GuestCartManagement/Plugin/AuthorizationTest.php @@ -36,7 +36,7 @@ protected function setUp() /** * @expectedException \Magento\Framework\Exception\StateException - * @expectedMessage You don't have the correct permissions to assign the customer to the cart. + * @expectedExceptionMessage You don't have the correct permissions to assign the customer to the cart. */ public function testBeforeAssignCustomer() { diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/UpdaterTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/UpdaterTest.php index af47f6276705b..7933da7c5fe37 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/UpdaterTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/UpdaterTest.php @@ -92,7 +92,7 @@ protected function setUp() /** * @expectedException \InvalidArgumentException - * @ExceptedExceptionMessage The qty value is required to update quote item. + * @expectedExceptionMessage The qty value is required to update quote item. */ public function testUpdateNoQty() { diff --git a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php index e3d5528d62c70..89fea2bec73a8 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php @@ -102,7 +102,7 @@ protected function setUp() /** * @expectedException \Magento\Framework\Exception\NoSuchEntityException - * @expected ExceptionMessage error345 + * @expectedExceptionMessage error345 */ public function testSetAddressValidationFailed() { diff --git a/app/code/Magento/Search/Test/Unit/Model/SynonymGroupRepositoryTest.php b/app/code/Magento/Search/Test/Unit/Model/SynonymGroupRepositoryTest.php index f62c07b149c0e..4532479c482b5 100644 --- a/app/code/Magento/Search/Test/Unit/Model/SynonymGroupRepositoryTest.php +++ b/app/code/Magento/Search/Test/Unit/Model/SynonymGroupRepositoryTest.php @@ -53,7 +53,7 @@ public function testSaveCreate() /** * @expectedException \Magento\Search\Model\Synonym\MergeConflictException - * @expecteExceptionMessage (c,d,e) + * @expectedExceptionMessage Merge conflict with existing synonym group(s): (a,b,c) */ public function testSaveCreateMergeConflict() { @@ -138,7 +138,7 @@ public function testSaveUpdate() /** * @expectedException \Magento\Search\Model\Synonym\MergeConflictException - * @expecteExceptionMessage (d,h,i) + * @expectedExceptionMessage (d,h,i) */ public function testSaveUpdateMergeConflict() { diff --git a/app/code/Magento/Theme/Test/Unit/Model/Theme/Source/ThemeTest.php b/app/code/Magento/Theme/Test/Unit/Model/Theme/Source/ThemeTest.php index 5cb265d3d628b..c06e2626034a7 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/Theme/Source/ThemeTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/Theme/Source/ThemeTest.php @@ -10,7 +10,6 @@ class ThemeTest extends \PHPUnit\Framework\TestCase { /** - * @true * @return void * @covers \Magento\Theme\Model\Theme\Source\Theme::__construct * @covers \Magento\Theme\Model\Theme\Source\Theme::getAllOptions diff --git a/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php b/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php index f91401e43ea80..50d82b19d1045 100644 --- a/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php +++ b/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php @@ -66,7 +66,8 @@ public function testNotApplyFilterModifier() /** * @return void - * @assertException \Magento\Framework\Exception\LocalizedException + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Condition type "not_allowed" is not allowed */ public function testApplyFilterModifierWithNotAllowedCondition() { @@ -78,7 +79,7 @@ public function testApplyFilterModifierWithNotAllowedCondition() ] ]); $this->dataProvider->expects($this->never())->method('addFilter'); - $this->unit->applyFilterModifier($this->dataProvider, 'test'); + $this->unit->applyFilterModifier($this->dataProvider, 'filter'); } /** diff --git a/lib/internal/Magento/Framework/App/Test/Unit/ErrorHandlerTest.php b/lib/internal/Magento/Framework/App/Test/Unit/ErrorHandlerTest.php index 4b904cc2b55bd..bba4d67ddd108 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/ErrorHandlerTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/ErrorHandlerTest.php @@ -56,9 +56,9 @@ public function testHandlerException($errorNo, $errorPhrase) $errorFile = 'test_file'; $errorLine = 'test_error_line'; - $exceptedExceptionMessage = sprintf('%s: %s in %s on line %s', $errorPhrase, $errorStr, $errorFile, $errorLine); + $expectedExceptionMessage = sprintf('%s: %s in %s on line %s', $errorPhrase, $errorStr, $errorFile, $errorLine); $this->expectException('Exception'); - $this->expectExceptionMessage($exceptedExceptionMessage); + $this->expectExceptionMessage($expectedExceptionMessage); $this->object->handler($errorNo, $errorStr, $errorFile, $errorLine); } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Response/Http/FileFactoryTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Response/Http/FileFactoryTest.php index 11e305f806ba2..7ad2f21c89d71 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Response/Http/FileFactoryTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Response/Http/FileFactoryTest.php @@ -67,7 +67,7 @@ public function testCreateIfContentDoesntHaveRequiredKeys() /** * @expectedException \Exception - * @exceptedExceptionMessage File not found + * @expectedExceptionMessage File not found */ public function testCreateIfFileNotExist() { diff --git a/lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php b/lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php index 807a70ecd7599..f39a91161c1f5 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php @@ -122,7 +122,7 @@ public function testGetLayout() /** * @expectedException \RuntimeException - * @exceptedExceptionMessage 'Layout must be loaded only once.' + * @expectedExceptionMessage Layout must be loaded only once. */ public function testLoadLayoutWhenLayoutAlreadyLoaded() { diff --git a/lib/internal/Magento/Framework/Profiler/Test/Unit/Driver/Standard/StatTest.php b/lib/internal/Magento/Framework/Profiler/Test/Unit/Driver/Standard/StatTest.php index d694697284f8e..df74eeec972ba 100644 --- a/lib/internal/Magento/Framework/Profiler/Test/Unit/Driver/Standard/StatTest.php +++ b/lib/internal/Magento/Framework/Profiler/Test/Unit/Driver/Standard/StatTest.php @@ -395,7 +395,7 @@ public function fetchDataProvider() /** * @expectedException \InvalidArgumentException - * @expectedMessage Timer "foo" doesn't exist. + * @expectedExceptionMessage Timer "foo" doesn't exist. */ public function testFetchInvalidTimer() { @@ -404,7 +404,7 @@ public function testFetchInvalidTimer() /** * @expectedException \InvalidArgumentException - * @expectedMessage Timer "foo" doesn't have value for "bar". + * @expectedExceptionMessage Timer "foo" doesn't have value for "bar". */ public function testFetchInvalidKey() { diff --git a/setup/src/Magento/Setup/Test/Unit/Module/I18n/Parser/ParserTest.php b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Parser/ParserTest.php index 76c5a6d031399..d429d0a0c9953 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/I18n/Parser/ParserTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Parser/ParserTest.php @@ -39,7 +39,7 @@ protected function setUp() * @param array $jsFiles * @param array $phpMap * @param array $jsMap - * @paran array $phraseFactoryMap + * @param array $phraseFactoryMap * @param array $expectedResult * @dataProvider addPhraseDataProvider */ From 4cf4884343010b2c0dc770ed3af6afb558b0d19b Mon Sep 17 00:00:00 2001 From: Rus0 <andonid88@gmail.com> Date: Fri, 26 Oct 2018 14:50:55 -0500 Subject: [PATCH 524/812] Resolves issue 6731 by adding a custom message for refunding shipping --- .../Sales/Model/Order/Creditmemo/Total/Discount.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php index 0cc4143e569db..c62f6459a5e91 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php @@ -10,6 +10,7 @@ class Discount extends AbstractTotal /** * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo * @return $this + * @throws \Magento\Framework\Exception\LocalizedException */ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) { @@ -26,6 +27,16 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) * basing on how much shipping should be refunded. */ $baseShippingAmount = $this->getBaseShippingAmount($creditmemo); + + /** + * If credit memo's shipping amount is set and Order's shipping amount is 0, + * throw exception with differente message + */ + if ( $baseShippingAmount && $order->getBaseShippingAmount() <= 0 ) { + throw new \Magento\Framework\Exception\LocalizedException( + new \Magento\Framework\Phrase("You can not refund shipping if there is no shipping amount.",[]) + ); + } if ($baseShippingAmount) { $baseShippingDiscount = $baseShippingAmount * $order->getBaseShippingDiscountAmount() / From b02dbc6f69ef9b2a48946218446302b204a6966e Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <korshenk@adobe.com> Date: Fri, 26 Oct 2018 15:59:32 -0500 Subject: [PATCH 525/812] Update app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php Co-Authored-By: Rus0 <andonid88@gmail.com> --- .../Magento/Sales/Model/Order/Creditmemo/Total/Discount.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php index c62f6459a5e91..d33374d5430ad 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php @@ -30,7 +30,7 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) /** * If credit memo's shipping amount is set and Order's shipping amount is 0, - * throw exception with differente message + * throw exception with different message */ if ( $baseShippingAmount && $order->getBaseShippingAmount() <= 0 ) { throw new \Magento\Framework\Exception\LocalizedException( From d3e576f9ff770aa0d9475ff24f29eb0c4c8780b9 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <korshenk@adobe.com> Date: Fri, 26 Oct 2018 15:59:43 -0500 Subject: [PATCH 526/812] Update app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php Co-Authored-By: Rus0 <andonid88@gmail.com> --- .../Magento/Sales/Model/Order/Creditmemo/Total/Discount.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php index d33374d5430ad..53faa4e23488c 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php @@ -32,7 +32,7 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) * If credit memo's shipping amount is set and Order's shipping amount is 0, * throw exception with different message */ - if ( $baseShippingAmount && $order->getBaseShippingAmount() <= 0 ) { + if ($baseShippingAmount && $order->getBaseShippingAmount() <= 0) { throw new \Magento\Framework\Exception\LocalizedException( new \Magento\Framework\Phrase("You can not refund shipping if there is no shipping amount.",[]) ); From 02dc040145559d88a86a971b5c0e08076735534c Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <korshenk@adobe.com> Date: Fri, 26 Oct 2018 15:59:57 -0500 Subject: [PATCH 527/812] Update app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php Co-Authored-By: Rus0 <andonid88@gmail.com> --- .../Magento/Sales/Model/Order/Creditmemo/Total/Discount.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php index 53faa4e23488c..749a12f7d8b55 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php @@ -34,7 +34,7 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) */ if ($baseShippingAmount && $order->getBaseShippingAmount() <= 0) { throw new \Magento\Framework\Exception\LocalizedException( - new \Magento\Framework\Phrase("You can not refund shipping if there is no shipping amount.",[]) + new \Magento\Framework\Phrase("You can not refund shipping if there is no shipping amount.", []) ); } if ($baseShippingAmount) { From 73af54a06edfb2a2f4e2582f229dc4d301db9df4 Mon Sep 17 00:00:00 2001 From: Rus0 <andonid88@gmail.com> Date: Fri, 26 Oct 2018 16:16:29 -0500 Subject: [PATCH 528/812] Correcting Unit tests --- .../Order/Creditmemo/Total/DiscountTest.php | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php index 18efef38b204c..a9a859ea1b5d6 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php @@ -74,7 +74,7 @@ public function testCollect() $this->orderMock->expects($this->once()) ->method('getBaseShippingDiscountAmount') ->willReturn(1); - $this->orderMock->expects($this->exactly(2)) + $this->orderMock->expects($this->exactly(3)) ->method('getBaseShippingAmount') ->willReturn(1); $this->orderMock->expects($this->once()) @@ -150,7 +150,7 @@ public function testCollectNoBaseShippingAmount() $this->orderMock->expects($this->once()) ->method('getBaseShippingDiscountAmount') ->willReturn(1); - $this->orderMock->expects($this->exactly(2)) + $this->orderMock->expects($this->exactly(3)) ->method('getBaseShippingAmount') ->willReturn(1); $this->orderMock->expects($this->once()) @@ -269,4 +269,30 @@ public function testCollectZeroShipping() ); $this->assertEquals($this->total, $this->total->collect($this->creditmemoMock)); } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage You can not refund shipping if there is no shipping amount. + */ + public function testCollectNonZeroShipping() + { + $this->creditmemoMock->expects($this->once()) + ->method('setDiscountAmount') + ->willReturnSelf(); + $this->creditmemoMock->expects($this->once()) + ->method('setBaseDiscountAmount') + ->willReturnSelf(); + $this->creditmemoMock->expects($this->once()) + ->method('getOrder') + ->willReturn($this->orderMock); + $this->creditmemoMock->expects($this->once()) + ->method('getBaseShippingAmount') + ->willReturn('10.0000'); + $this->orderMock->expects($this->never()) + ->method('getBaseShippingDiscountAmount'); + $this->orderMock->expects($this->once()) + ->method('getBaseShippingAmount') + ->willReturn( '0.0000'); + $this->assertEquals($this->total, $this->total->collect($this->creditmemoMock)); + } } From a3dfdd34cbe4209285c8bc785c5255406353e684 Mon Sep 17 00:00:00 2001 From: Wiard van Rij <vanrij@redkiwi.nl> Date: Fri, 26 Oct 2018 23:38:53 +0200 Subject: [PATCH 529/812] Updates php.ini sample --- php.ini.sample | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/php.ini.sample b/php.ini.sample index 8a7d13cf42b4e..17c8cb52abb70 100644 --- a/php.ini.sample +++ b/php.ini.sample @@ -1,32 +1,13 @@ ; Copyright © Magento, Inc. All rights reserved. ; See COPYING.txt for license details. -; This file is for CGI/FastCGI installations. -; Try copying it to php5.ini, if it doesn't work ; adjust memory limit +; Our detailed recommendations are: -memory_limit = 64M +; Compiling code or deploying static assets, 756M +; Installing and updating Magento components from Magento Marketplace, 2G +; Testing, ~3-4G -max_execution_time = 18000 +memory_limit = 2G -; disable automatic session start -; before autoload was initialized - -flag session.auto_start = off - -; enable resulting html compression - -zlib.output_compression = on - -; disable user agent verification to not break multiple image upload - -suhosin.session.cryptua = off - -; PHP for some reason ignores this setting in system php.ini -; and disables mcrypt if this line is missing in local php.ini - -extension=mcrypt.so - -; Disable PHP errors, notices and warnings output in production mode to prevent exposing sensitive information. - -display_errors = Off +; For further details refer to the technology stack requirements of your Magento installation \ No newline at end of file From e1a1c7b280bfbb6c8cbcaf205d0d7f7dbb882878 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Fri, 26 Oct 2018 16:50:31 -0500 Subject: [PATCH 530/812] ENGCOM-3292 catalog:images:resize total images count calculates incorrectly #18387: #18807 --- .../Magento/Catalog/Model/ResourceModel/Product/Image.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php index 5a290d5141e80..068580927b96a 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php @@ -12,6 +12,9 @@ use Magento\Framework\DB\Select; use Magento\Framework\App\ResourceConnection; +/* + * Class for retrieval of all product images + */ class Image { /** @@ -73,6 +76,7 @@ public function getAllProductImages(): \Generator /** * Get the number of unique pictures of products + * * @return int */ public function getCountAllProductImages(): int @@ -88,6 +92,8 @@ public function getCountAllProductImages(): int } /** + * Return Select to fetch all products images + * * @return Select */ private function getVisibleImagesSelect(): Select From ba69bfec127bed8c39c7d9e7b73d10b54449b158 Mon Sep 17 00:00:00 2001 From: Wiard van Rij <wiard@outlook.com> Date: Sat, 27 Oct 2018 01:06:42 +0200 Subject: [PATCH 531/812] Fixes theme header logo and icon upload --- .../Theme/view/adminhtml/ui_component/design_config_form.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Theme/view/adminhtml/ui_component/design_config_form.xml b/app/code/Magento/Theme/view/adminhtml/ui_component/design_config_form.xml index 8d4580f90c7b1..bc1f36222dd60 100644 --- a/app/code/Magento/Theme/view/adminhtml/ui_component/design_config_form.xml +++ b/app/code/Magento/Theme/view/adminhtml/ui_component/design_config_form.xml @@ -54,7 +54,7 @@ <collapsible>true</collapsible> <label translate="true">HTML Head</label> </settings> - <field name="head_shortcut_icon" formElement="fileUploader"> + <field name="head_shortcut_icon" formElement="imageUploader"> <settings> <notice translate="true">Not all browsers support all these formats!</notice> <label translate="true">Favicon Icon</label> @@ -151,7 +151,7 @@ <collapsible>true</collapsible> <label translate="true">Header</label> </settings> - <field name="header_logo_src" formElement="fileUploader"> + <field name="header_logo_src" formElement="imageUploader"> <settings> <label translate="true">Logo Image</label> <componentType>imageUploader</componentType> From cd97592752a02a6b3dcda3494f18557dcb93b6d3 Mon Sep 17 00:00:00 2001 From: speedy008 <kajal10395@gmail.com> Date: Sat, 27 Oct 2018 12:01:56 +0530 Subject: [PATCH 532/812] Downloadable products - Downloadable Information - Link design issue-#18854 --- .../adminhtml/Magento/backend/web/css/source/forms/_fields.less | 1 - 1 file changed, 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less index b3e4a91180b96..3503abcc30468 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less @@ -520,7 +520,6 @@ & > .admin__field-label { #mix-grid .column(@field-label-grid__column, @field-grid__columns); - background: @color-white; cursor: pointer; left: 0; position: absolute; From f6b0a2abfa0c95ce406a707a3ede42dbad5cfc22 Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Sat, 27 Oct 2018 17:58:00 +0300 Subject: [PATCH 533/812] magento/magento2#18387: catalog:images:resize fails to process all images -> Possible underlying Magento/Framework/DB/Query/Generator issue - fix unit test - now it can test also not only full batches, but partial as well (139 images with batch size 100); --- .../Model/ResourceModel/Product/ImageTest.php | 170 +++++++++++------- 1 file changed, 109 insertions(+), 61 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php index 9c783e237ab24..1866138cf16b6 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php @@ -16,6 +16,11 @@ class ImageTest extends \PHPUnit\Framework\TestCase { + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + protected $objectManager; + /** * @var AdapterInterface | \PHPUnit_Framework_MockObject_MockObject */ @@ -31,41 +36,14 @@ class ImageTest extends \PHPUnit\Framework\TestCase */ protected $resourceMock; - /** - * @var Image - */ - protected $imageModel; - - /** - * @var int - */ - protected $imagesCount = 50; - - /** - * @var int - */ - protected $batchSize = 10; - protected function setUp(): void { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - + $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->connectionMock = $this->createMock(AdapterInterface::class); - $this->resourceMock = $this->createMock(ResourceConnection::class); $this->resourceMock->method('getConnection')->willReturn($this->connectionMock); $this->resourceMock->method('getTableName')->willReturnArgument(0); - $this->generatorMock = $this->createMock(Generator::class); - - $this->imageModel = $objectManager->getObject( - Image::class, - [ - 'generator' => $this->generatorMock, - 'resourceConnection' => $this->resourceMock, - 'batchSize' => $this->batchSize - ] - ); } /** @@ -93,7 +71,11 @@ protected function getVisibleImagesSelectMock(): \PHPUnit_Framework_MockObject_M return $selectMock; } - public function testGetCountAllProductImages(): void + /** + * @param int $imagesCount + * @dataProvider dataProvider + */ + public function testGetCountAllProductImages(int $imagesCount): void { $selectMock = $this->getVisibleImagesSelectMock(); $selectMock->expects($this->exactly(2)) @@ -113,59 +95,125 @@ public function testGetCountAllProductImages(): void $this->connectionMock->expects($this->once()) ->method('fetchOne') ->with($selectMock) - ->willReturn($this->imagesCount); + ->willReturn($imagesCount); + + $imageModel = $this->objectManager->getObject( + Image::class, + [ + 'generator' => $this->generatorMock, + 'resourceConnection' => $this->resourceMock + ] + ); - $this->assertSame($this->imagesCount, $this->imageModel->getCountAllProductImages()); + $this->assertSame($imagesCount, $imageModel->getCountAllProductImages()); } - public function testGetAllProductImages(): void + /** + * @param int $imagesCount + * @param int $batchSize + * @dataProvider dataProvider + */ + public function testGetAllProductImages(int $imagesCount, int $batchSize): void { - $getBatchIteratorMock = function ($selectMock, $imagesCount, $batchSize): array { - $result = []; - $count = $imagesCount / $batchSize; - while ($count) { - $count--; - $result[$count] = $selectMock; - } - - return $result; - }; - - $getFetchResults = function ($batchSize): array { - $result = []; - $count = $batchSize; - while ($count) { - $count--; - $result[$count] = $count; - } - - return $result; - }; - $this->connectionMock->expects($this->once()) ->method('select') ->willReturn($this->getVisibleImagesSelectMock()); - $fetchResult = $getFetchResults($this->batchSize); - $this->connectionMock->expects($this->exactly($this->imagesCount / $this->batchSize)) + $batchCount = (int)ceil($imagesCount / $batchSize); + $fetchResultsCallback = $this->getFetchResultCallbackForBatches($imagesCount, $batchSize); + $this->connectionMock->expects($this->exactly($batchCount)) ->method('fetchAll') - ->willReturn($fetchResult); + ->will($this->returnCallback($fetchResultsCallback)); /** @var Select | \PHPUnit_Framework_MockObject_MockObject $selectMock */ $selectMock = $this->getMockBuilder(Select::class) ->disableOriginalConstructor() ->getMock(); - $batchIteratorMock = $getBatchIteratorMock($selectMock, $this->imagesCount, $this->batchSize); $this->generatorMock->expects($this->once()) ->method('generate') ->with( 'value_id', $selectMock, - $this->batchSize, + $batchSize, \Magento\Framework\DB\Query\BatchIteratorInterface::NON_UNIQUE_FIELD_ITERATOR - )->willReturn($batchIteratorMock); + )->will($this->returnCallback($this->getBatchIteratorCallback($selectMock, $batchCount))); - $this->assertCount($this->imagesCount, $this->imageModel->getAllProductImages()); + $imageModel = $this->objectManager->getObject( + Image::class, + [ + 'generator' => $this->generatorMock, + 'resourceConnection' => $this->resourceMock, + 'batchSize' => $batchSize + ] + ); + + $this->assertCount($imagesCount, $imageModel->getAllProductImages()); + } + + /** + * @param int $imagesCount + * @param int $batchSize + * @return \Closure + */ + protected function getFetchResultCallbackForBatches(int $imagesCount, int $batchSize): \Closure + { + $fetchResultsCallback = function () use (&$imagesCount, $batchSize) { + $batchSize = ($imagesCount >= $batchSize) ? $batchSize : $imagesCount; + $imagesCount -= $batchSize; + + $getFetchResults = function ($batchSize): array { + $result = []; + $count = $batchSize; + while ($count) { + $count--; + $result[$count] = $count; + } + + return $result; + }; + + return $getFetchResults($batchSize); + }; + + return $fetchResultsCallback; + } + + /** + * @param Select | \PHPUnit_Framework_MockObject_MockObject $selectMock + * @param int $batchCount + * @return \Closure + */ + protected function getBatchIteratorCallback( + \PHPUnit_Framework_MockObject_MockObject $selectMock, + int $batchCount + ): \Closure + { + $getBatchIteratorCallback = function () use ($batchCount, $selectMock): array { + $result = []; + $count = $batchCount; + while ($count) { + $count--; + $result[$count] = $selectMock; + } + + return $result; + }; + + return $getBatchIteratorCallback; + } + + /** + * Data Provider + * @return array + */ + public function dataProvider(): array + { + return [ + [300, 100], + [139, 100], + [67, 10], + [154, 47] + ]; } } From 546e7ce1c64fa8f0290eabd26070eac4837cb39e Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Sat, 27 Oct 2018 17:59:22 +0300 Subject: [PATCH 534/812] magento/magento2#18387: catalog:images:resize fails to process all images -> Possible underlying Magento/Framework/DB/Query/Generator issue - fix unit test - now it can test also not only full batches, but partial as well (139 images with batch size 100); --- .../Test/Unit/Model/ResourceModel/Product/ImageTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php index 1866138cf16b6..1a1eebf30f7f6 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php @@ -210,10 +210,12 @@ protected function getBatchIteratorCallback( public function dataProvider(): array { return [ + [300, 300], [300, 100], [139, 100], [67, 10], - [154, 47] + [154, 47], + [0, 100] ]; } } From 84a48b431c6bd250466fff9c28a4053987e23f9c Mon Sep 17 00:00:00 2001 From: Wiard van Rij <wiard@outlook.com> Date: Sat, 27 Oct 2018 17:22:28 +0200 Subject: [PATCH 535/812] Removes php.ini.sample as its obsolete --- php.ini.sample | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 php.ini.sample diff --git a/php.ini.sample b/php.ini.sample deleted file mode 100644 index 17c8cb52abb70..0000000000000 --- a/php.ini.sample +++ /dev/null @@ -1,13 +0,0 @@ -; Copyright © Magento, Inc. All rights reserved. -; See COPYING.txt for license details. - -; adjust memory limit -; Our detailed recommendations are: - -; Compiling code or deploying static assets, 756M -; Installing and updating Magento components from Magento Marketplace, 2G -; Testing, ~3-4G - -memory_limit = 2G - -; For further details refer to the technology stack requirements of your Magento installation \ No newline at end of file From 4a283722cdb25ef030d8100bc20c3fa16c2e3d91 Mon Sep 17 00:00:00 2001 From: Artem Klimov <art.klimoff@gmail.com> Date: Sat, 27 Oct 2018 19:36:06 +0300 Subject: [PATCH 536/812] resolve magento 2.3 update conflicts --- lib/internal/Magento/Framework/GraphQl/Config.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/GraphQl/Config.php b/lib/internal/Magento/Framework/GraphQl/Config.php index bfd8f330c6123..481d75ed35893 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config.php +++ b/lib/internal/Magento/Framework/GraphQl/Config.php @@ -10,6 +10,7 @@ use Magento\Framework\Config\DataInterface; use Magento\Framework\GraphQl\Config\ConfigElementFactoryInterface; use Magento\Framework\GraphQl\Config\ConfigElementInterface; +use Magento\Framework\GraphQl\Query\Fields as QueryFields; /** * Provides access to typing information for a configured GraphQL schema. From b8d2663b72438fdda17dcd793c349681a5c784c6 Mon Sep 17 00:00:00 2001 From: Artem Klimov <art.klimoff@gmail.com> Date: Sat, 27 Oct 2018 19:45:50 +0300 Subject: [PATCH 537/812] resolve magento 2.3 update conflicts --- lib/internal/Magento/Framework/GraphQl/Config.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Config.php b/lib/internal/Magento/Framework/GraphQl/Config.php index 481d75ed35893..75b6c64e9d24f 100644 --- a/lib/internal/Magento/Framework/GraphQl/Config.php +++ b/lib/internal/Magento/Framework/GraphQl/Config.php @@ -65,10 +65,12 @@ public function getConfigElement(string $configElementName) : ConfigElementInter } $fieldsInQuery = $this->queryFields->getFieldsUsedInQuery(); - if (isset($data['fields']) && !empty($fieldsInQuery)) { - foreach ($data['fields'] as $fieldName => $fieldConfig) { - if (!isset($fieldsInQuery[$fieldName])) { - unset($data['fields'][$fieldName]); + if (isset($data['fields'])) { + if (!empty($fieldsInQuery)) { + foreach ($data['fields'] as $fieldName => $fieldConfig) { + if (!isset($fieldsInQuery[$fieldName])) { + unset($data['fields'][$fieldName]); + } } } From d2f691dc08f48e1620a096648c94344f8ef189b3 Mon Sep 17 00:00:00 2001 From: Hugo <hugovk@users.noreply.github.com> Date: Sat, 27 Oct 2018 23:06:25 +0300 Subject: [PATCH 538/812] Fix spelling --- CHANGELOG.md | 8 ++++---- .../Controller/Adminhtml/Bulk/Details.php | 2 +- app/code/Magento/Backend/App/Request/BackendValidator.php | 2 +- .../Backend/Block/Widget/Grid/Column/Filter/Theme.php | 2 +- app/code/Magento/Backend/Block/Widget/Tabs.php | 2 +- .../Backend/Console/Command/AbstractCacheCommand.php | 2 +- .../Magento/Backend/Test/Unit/Model/Menu/ConfigTest.php | 2 +- app/code/Magento/Backend/etc/adminhtml/system.xml | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc722b6d61b33..b86c7b79a0cbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -157,7 +157,7 @@ To get detailed information about changes in Magento 2.1.0, please visit [Magent * Updated styles * Sample Data: * Improved sample data installation UX - * Updated sample data with Product Heros, color swatches, MAP and rule based product relations + * Updated sample data with Product Heroes, color swatches, MAP and rule based product relations * Improved sample data upgrade flow * Added the ability to log errors and set the error flag during sample data installation * Various improvements: @@ -2284,7 +2284,7 @@ Tests: * Fixed an issue where no results were found for Coupons reports * Fixed an issue with incremental Qty setting * Fixed an issue with allowing importing of negative weight values - * Fixed an issue with Inventory - Only X left Treshold being not dependent on Qty for Item's Status to Become Out of Stock + * Fixed an issue with Inventory - Only X left Threshold being not dependent on Qty for Item's Status to Become Out of Stock * Fixed an issue where the "Catalog Search Index index was rebuilt." message was displayed when reindexing the Catalog Search index * Search module: * Integrated the Search library to the advanced search functionality @@ -2706,7 +2706,7 @@ Tests: * Ability to support extensible service data objects * No Code Duplication in Root Templates * Fixed bugs: - * Persistance session application. Loggin out the customer + * Persistence session application. Logging out the customer * Placing the order with two terms and conditions * Saving of custom option by service catalogProductCustomOptionsWriteServiceV1 * Placing the order on frontend if enter in the street address line 1 and 2 255 symbols @@ -2965,7 +2965,7 @@ Tests: * Fixed an issue with incorrect items label for the cases when there are more than one item in the category * Fixed an issue when configurable product was out of stock in Google Shopping while being in stock in the Magento backend * Fixed an issue when swipe gesture in menu widget was not supported on mobile - * Fixed an issue when it was impossible to enter alpha-numeric zip code on the stage of estimating shipping and tax rates + * Fixed an issue when it was impossible to enter alphanumeric zip code on the stage of estimating shipping and tax rates * Fixed an issue when custom price was not applied when editing an order * Fixed an issue when items were not returned to stock after unsuccessful order was placed * Fixed an issue when error message appeared "Cannot save the credit memo” while creating credit memo diff --git a/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php b/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php index 9e9dbd3dd67c5..5571c20f526cc 100644 --- a/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php +++ b/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php @@ -6,7 +6,7 @@ namespace Magento\AsynchronousOperations\Controller\Adminhtml\Bulk; /** - * Class View Opertion Details Controller + * Class View Operation Details Controller */ class Details extends \Magento\Backend\App\Action { diff --git a/app/code/Magento/Backend/App/Request/BackendValidator.php b/app/code/Magento/Backend/App/Request/BackendValidator.php index 878f9cb4dc4c1..eed4fbb643d3e 100644 --- a/app/code/Magento/Backend/App/Request/BackendValidator.php +++ b/app/code/Magento/Backend/App/Request/BackendValidator.php @@ -166,7 +166,7 @@ public function validate( ActionInterface $action ): void { if ($action instanceof AbstractAction) { - //Abstract Action has build-in validation. + //Abstract Action has built-in validation. if (!$action->_processUrlKeys()) { throw new InvalidRequestException($action->getResponse()); } diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php index d49ad2941146b..5db5dc59b4e5b 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php +++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php @@ -54,7 +54,7 @@ public function getHtml() } /** - * Retrieve options setted in column. + * Retrieve options set in column. * Or load if options was not set. * * @return array diff --git a/app/code/Magento/Backend/Block/Widget/Tabs.php b/app/code/Magento/Backend/Block/Widget/Tabs.php index 333904e398cf5..b390e2fa7d150 100644 --- a/app/code/Magento/Backend/Block/Widget/Tabs.php +++ b/app/code/Magento/Backend/Block/Widget/Tabs.php @@ -468,7 +468,7 @@ public function getTabContent($tab) } /** - * Mark tabs as dependant of each other + * Mark tabs as dependent of each other * Arbitrary number of tabs can be specified, but at least two * * @param string $tabOneId diff --git a/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php b/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php index 70b01046f6afe..ecea5716f653d 100644 --- a/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php +++ b/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php @@ -17,7 +17,7 @@ abstract class AbstractCacheCommand extends Command { /** - * Input option bootsrap + * Input option bootstrap */ const INPUT_KEY_BOOTSTRAP = 'bootstrap'; diff --git a/app/code/Magento/Backend/Test/Unit/Model/Menu/ConfigTest.php b/app/code/Magento/Backend/Test/Unit/Model/Menu/ConfigTest.php index 260a38a481b3c..2b5f644e35977 100644 --- a/app/code/Magento/Backend/Test/Unit/Model/Menu/ConfigTest.php +++ b/app/code/Magento/Backend/Test/Unit/Model/Menu/ConfigTest.php @@ -168,6 +168,6 @@ public function testGetMenuGenericExceptionIsNotLogged() } catch (\Exception $e) { return; } - $this->fail("Generic \Exception was not throwed"); + $this->fail("Generic \Exception was not thrown"); } } diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index e061455acbe6b..cc12e138826ea 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -129,7 +129,7 @@ <field id="*/*/template_hints_storefront">1</field> <field id="*/*/template_hints_storefront_show_with_parameter">1</field> </depends> - <comment>Add the following paramater to the URL to show template hints ?templatehints=[parameter_value]</comment> + <comment>Add the following parameter to the URL to show template hints ?templatehints=[parameter_value]</comment> </field> <field id="template_hints_admin" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Enabled Template Path Hints for Admin</label> From afdcbb549e8b7faed858bfa9d9a94c03d180b657 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Sun, 28 Oct 2018 09:40:23 +0200 Subject: [PATCH 539/812] Remove duplicated selector --- .../luma/Magento_Checkout/web/css/source/module/_cart.less | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less index 9e3a28be4c90e..cf7a909889584 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less @@ -628,9 +628,6 @@ &-item-details { padding-bottom: 35px; - } - - &-item-details { display: table-cell; vertical-align: top; white-space: normal; From dba69444975fab128a0764e4516af29331624e68 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <mitry@atwix.com> Date: Sun, 28 Oct 2018 11:42:31 +0200 Subject: [PATCH 540/812] Add missing unit test for WishlistSettings plugin --- .../Ui/DataProvider/WishlistSettingsTest.php | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 app/code/Magento/Wishlist/Test/Unit/Plugin/Ui/DataProvider/WishlistSettingsTest.php diff --git a/app/code/Magento/Wishlist/Test/Unit/Plugin/Ui/DataProvider/WishlistSettingsTest.php b/app/code/Magento/Wishlist/Test/Unit/Plugin/Ui/DataProvider/WishlistSettingsTest.php new file mode 100644 index 0000000000000..aa3b956e12153 --- /dev/null +++ b/app/code/Magento/Wishlist/Test/Unit/Plugin/Ui/DataProvider/WishlistSettingsTest.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Wishlist\Test\Unit\Plugin\Ui\DataProvider; + +use Magento\Catalog\Ui\DataProvider\Product\Listing\DataProvider; +use Magento\Wishlist\Helper\Data; +use Magento\Wishlist\Plugin\Ui\DataProvider\WishlistSettings; + +/** + * Covers \Magento\Wishlist\Plugin\Ui\DataProvider\WishlistSettings + */ +class WishlistSettingsTest extends \PHPUnit\Framework\TestCase +{ + /** + * Testable Object + * + * @var WishlistSettings + */ + private $wishlistSettings; + + /** + * @var Data|\PHPUnit_Framework_MockObject_MockObject + */ + private $helperMock; + + /** + * Set Up + * + * @return void + */ + protected function setUp() + { + $this->helperMock = $this->createMock(Data::class); + $this->wishlistSettings = new WishlistSettings($this->helperMock); + } + + /** + * Test afterGetData method + * + * @return void + */ + public function testAfterGetData() + { + /** @var DataProvider|\PHPUnit_Framework_MockObject_MockObject $subjectMock */ + $subjectMock = $this->createMock(DataProvider::class); + $result = []; + $isAllow = true; + $this->helperMock->expects($this->once())->method('isAllow')->willReturn(true); + + $expected = ['allowWishlist' => $isAllow]; + $actual = $this->wishlistSettings->afterGetData($subjectMock, $result); + self::assertEquals($expected, $actual); + } +} From 22abbcbb6ac21b32ca25b93f55bba8079a2d56c9 Mon Sep 17 00:00:00 2001 From: rahul <rahul@webkul.com> Date: Sun, 28 Oct 2018 15:37:38 +0530 Subject: [PATCH 541/812] fixed - can't import external http to https redirecting images by default csv import --- lib/internal/Magento/Framework/Filesystem/Driver/Http.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php index 236585fa61384..e43f35b072f1d 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php @@ -36,6 +36,11 @@ public function isExists($path) $status = $headers[0]; + /* Handling 302 redirection */ + if (strpos($status, '302 Found') !== false && isset($headers[1])) { + $status = $headers[1]; + } + if (strpos($status, '200 OK') === false) { $result = false; } else { From 8720e236d553c09afca227eb0d2e623463be0075 Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk <kolesnyk@adobe.com> Date: Sun, 28 Oct 2018 12:35:43 +0100 Subject: [PATCH 542/812] Bump MFTF version --- composer.json | 2 +- composer.lock | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index e2a646275d98b..7601bb34bb6ad 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.13.0", "lusitanian/oauth": "~0.8.10", - "magento/magento2-functional-testing-framework": "2.3.6", + "magento/magento2-functional-testing-framework": "2.3.9.x-dev", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index 2550f70f0be81..2ebd20b84852a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "18982aa4d36bcfd22cf073dfb578efdb", + "content-hash": "d9acbe01fc68b7e28ba36a164d59439f", "packages": [ { "name": "braintree/braintree_php", @@ -6351,16 +6351,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.3.6", + "version": "2.3.9.x-dev", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "57021e12ded213a0031c4d4f6293e06ce6f144ce" + "reference": "9885925ea741d0b0eede35be09a45b62d9ef7c84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/57021e12ded213a0031c4d4f6293e06ce6f144ce", - "reference": "57021e12ded213a0031c4d4f6293e06ce6f144ce", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/9885925ea741d0b0eede35be09a45b62d9ef7c84", + "reference": "9885925ea741d0b0eede35be09a45b62d9ef7c84", "shasum": "" }, "require": { @@ -6418,7 +6418,7 @@ "magento", "testing" ], - "time": "2018-09-05T15:17:20+00:00" + "time": "2018-10-28T11:19:53+00:00" }, { "name": "moontoast/math", @@ -9041,6 +9041,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { + "magento/magento2-functional-testing-framework": 20, "phpmd/phpmd": 0 }, "prefer-stable": true, From 0be96a84e22ae552f3aff29b5fab3df94a60c384 Mon Sep 17 00:00:00 2001 From: Denis Papec <denis.papec@gmail.com> Date: Sun, 28 Oct 2018 20:50:05 +0000 Subject: [PATCH 543/812] Removed parameter from \Magento\ImportExport\Model\Source\Import\Behavior\Custom constructor --- .../Test/Unit/Model/Source/Import/Behavior/CustomTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Source/Import/Behavior/CustomTest.php b/app/code/Magento/ImportExport/Test/Unit/Model/Source/Import/Behavior/CustomTest.php index d073f3866bfe6..73b4f10b3b0f0 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Source/Import/Behavior/CustomTest.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Source/Import/Behavior/CustomTest.php @@ -32,7 +32,7 @@ class CustomTest extends \Magento\ImportExport\Test\Unit\Model\Source\Import\Abs protected function setUp() { parent::setUp(); - $this->_model = new \Magento\ImportExport\Model\Source\Import\Behavior\Custom([]); + $this->_model = new \Magento\ImportExport\Model\Source\Import\Behavior\Custom(); } /** From a9622b53819f7f5d06b95f6c6922dcdb4c5add84 Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk <kolesnyk@adobe.com> Date: Sun, 28 Oct 2018 18:28:44 +0100 Subject: [PATCH 544/812] Bump MFTF version - skip failing test --- .../Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml | 3 +++ composer.json | 2 +- composer.lock | 5 ++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml index 11bf03c1d5ee9..4b3d5c9258785 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddImageToCMSPageTinyMCE3Test.xml @@ -17,6 +17,9 @@ <description value="Verify that admin is able to upload image to CMS Page with TinyMCE3 enabled"/> <severity value="MAJOR"/> <testCaseId value="MAGETWO-95725"/> + <skip> + <issueId value="MC-5371" /> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> diff --git a/composer.json b/composer.json index 7601bb34bb6ad..770e93fd17e70 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.13.0", "lusitanian/oauth": "~0.8.10", - "magento/magento2-functional-testing-framework": "2.3.9.x-dev", + "magento/magento2-functional-testing-framework": "2.3.9", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index 2ebd20b84852a..43777f5c94864 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d9acbe01fc68b7e28ba36a164d59439f", + "content-hash": "b6dc9e7403d5f8b1c9d870e0ca0c8a12", "packages": [ { "name": "braintree/braintree_php", @@ -6351,7 +6351,7 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.3.9.x-dev", + "version": "2.3.9", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", @@ -9041,7 +9041,6 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "magento/magento2-functional-testing-framework": 20, "phpmd/phpmd": 0 }, "prefer-stable": true, From 48446c63090fd2d20c24ba2dede135001e600515 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Mon, 29 Oct 2018 09:24:32 +0200 Subject: [PATCH 545/812] ENGCOM-3161: [Forwardport] #4942 and bundle checkbox bug #18520. Fix functional tests. --- .../Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml index 4945308c26c4a..58806126aee30 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml @@ -95,7 +95,7 @@ <waitForPageLoad stepKey="waitForStorefront2"/> <!-- Check second one option to choose both of the options on the storefront --> - <click selector="{{StorefrontBundledSection.bundleOption('1','2')}}" stepKey="selectSecondBundleOption2"/> + <click selector="{{StorefrontBundledSection.nthBundledOption('1','2')}}" stepKey="selectSecondBundleOption2"/> <waitForPageLoad stepKey="waitForPriceUpdate3"/> <see stepKey="seeDoublePrice" selector="{{StorefrontBundledSection.configuredPrice}}" userInput="2,460.00"/> From 7ca0246619db085938bc31e949c35124479e5c5e Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 29 Oct 2018 13:53:26 +0200 Subject: [PATCH 546/812] ENGCOM-3184: Fixed functional test. --- .../Controller/Adminhtml/Product/Initialization/Helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index 8999b03b647a3..988d61986e3d2 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -463,7 +463,7 @@ private function fillProductOptions(Product $product, array $productOptions) private function convertSpecialFromDateStringToObject($productData) { if (isset($productData['special_from_date']) && $productData['special_from_date'] != '') { - $productData['special_from_date'] = $this->dateFilter->filter($productData['special_from_date']); + $productData['special_from_date'] = $this->getDateTimeFilter()->filter($productData['special_from_date']); $productData['special_from_date'] = new \DateTime($productData['special_from_date']); } From 8a64a2991dc979ade0ec0907a9de29a022f0e857 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Mon, 29 Oct 2018 14:43:57 +0200 Subject: [PATCH 547/812] MAGETWO-95536: [2.3] Admin users are deleted from role upon Role save - fixed - added test --- .../Integration/Plugin/Model/AdminUser.php | 8 +- .../Adminhtml/User/Role/SaveRole.php | 65 +++++++++++----- .../Adminhtml/User/Role/SaveRoleTest.php | 77 +++++++++++++++++++ .../User/_files/two_users_with_role.php | 52 +++++++++++++ .../_files/two_users_with_role_rollback.php | 21 +++++ 5 files changed, 201 insertions(+), 22 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php create mode 100644 dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php create mode 100644 dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php diff --git a/app/code/Magento/Integration/Plugin/Model/AdminUser.php b/app/code/Magento/Integration/Plugin/Model/AdminUser.php index df3766250caa7..7b2fa1981bce3 100644 --- a/app/code/Magento/Integration/Plugin/Model/AdminUser.php +++ b/app/code/Magento/Integration/Plugin/Model/AdminUser.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Integration\Plugin\Model; use Magento\Integration\Model\AdminTokenService; @@ -31,14 +32,15 @@ public function __construct( * * @param \Magento\User\Model\User $subject * @param \Magento\Framework\DataObject $object - * @return $this + * @return \Magento\User\Model\User + * @throws \Magento\Framework\Exception\LocalizedException */ public function afterSave( \Magento\User\Model\User $subject, \Magento\Framework\DataObject $object - ) { + ): \Magento\User\Model\User { $isActive = $object->getIsActive(); - if (isset($isActive) && $isActive == 0) { + if ($isActive !== null && $isActive == 0) { $this->adminTokenService->revokeAdminAccessToken($object->getId()); } return $subject; diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php index acd3430f5c25a..97ecb778b8cb1 100644 --- a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php +++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php @@ -11,6 +11,7 @@ use Magento\Authorization\Model\Acl\Role\Group as RoleGroup; use Magento\Authorization\Model\UserContextInterface; use Magento\Framework\Controller\ResultFactory; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\State\UserLockedException; use Magento\Security\Model\SecurityCookie; @@ -77,10 +78,8 @@ public function execute() $rid = $this->getRequest()->getParam('role_id', false); $resource = $this->getRequest()->getParam('resource', false); - $roleUsers = $this->getRequest()->getParam('in_role_user', null); - parse_str($roleUsers, $roleUsers); - $roleUsers = array_keys($roleUsers); - + $oldRoleUsers = $this->parseRequestVariable('in_role_user_old'); + $roleUsers = $this->parseRequestVariable('in_role_user'); $isAll = $this->getRequest()->getParam('all'); if ($isAll) { $resource = [$this->_objectManager->get(\Magento\Framework\Acl\RootResource::class)->getId()]; @@ -106,13 +105,9 @@ public function execute() $role->save(); $this->_rulesFactory->create()->setRoleId($role->getId())->setResources($resource)->saveRel(); - - $this->processPreviousUsers($role); - - foreach ($roleUsers as $nRuid) { - $this->_addUserToRole($nRuid, $role->getId()); - } - $this->messageManager->addSuccess(__('You saved the role.')); + $this->processPreviousUsers($role, $oldRoleUsers); + $this->processCurrentUsers($role, $roleUsers); + $this->messageManager->addSuccessMessage(__('You saved the role.')); } catch (UserLockedException $e) { $this->_auth->logout(); $this->getSecurityCookie()->setLogoutReasonCookie( @@ -120,14 +115,14 @@ public function execute() ); return $resultRedirect->setPath('*'); } catch (\Magento\Framework\Exception\AuthenticationException $e) { - $this->messageManager->addError( + $this->messageManager->addErrorMessage( __('The password entered for the current user is invalid. Verify the password and try again.') ); return $this->saveDataToSessionAndRedirect($role, $this->getRequest()->getPostValue(), $resultRedirect); } catch (\Magento\Framework\Exception\LocalizedException $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($e->getMessage()); } catch (\Exception $e) { - $this->messageManager->addError(__('An error occurred while saving this role.')); + $this->messageManager->addErrorMessage(__('An error occurred while saving this role.')); } return $resultRedirect->setPath('*/*/'); @@ -151,19 +146,30 @@ protected function validateUser() return $this; } + /** + * Parse request value from string + * + * @param string $paramName + * @return array + */ + private function parseRequestVariable($paramName): array + { + $value = $this->getRequest()->getParam($paramName, null); + parse_str($value, $value); + $value = array_keys($value); + return $value; + } + /** * Process previous users * * @param \Magento\Authorization\Model\Role $role + * @param array $oldRoleUsers * @return $this * @throws \Exception */ - protected function processPreviousUsers(\Magento\Authorization\Model\Role $role) + protected function processPreviousUsers(\Magento\Authorization\Model\Role $role, array $oldRoleUsers): self { - $oldRoleUsers = $this->getRequest()->getParam('in_role_user_old'); - parse_str($oldRoleUsers, $oldRoleUsers); - $oldRoleUsers = array_keys($oldRoleUsers); - foreach ($oldRoleUsers as $oUid) { $this->_deleteUserFromRole($oUid, $role->getId()); } @@ -171,12 +177,33 @@ protected function processPreviousUsers(\Magento\Authorization\Model\Role $role) return $this; } + /** + * Processes users to be assigned to roles + * + * @param \Magento\Authorization\Model\Role $role + * @param array $roleUsers + * @return $this + */ + private function processCurrentUsers(\Magento\Authorization\Model\Role $role, array $roleUsers): self + { + foreach ($roleUsers as $nRuid) { + try { + $this->_addUserToRole($nRuid, $role->getId()); + } catch (LocalizedException $e) { + $this->messageManager->addErrorMessage($e->getMessage()); + } + } + + return $this; + } + /** * Assign user to role * * @param int $userId * @param int $roleId * @return bool + * @throws LocalizedException */ protected function _addUserToRole($userId, $roleId) { diff --git a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php new file mode 100644 index 0000000000000..50b28e2bac0a9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\User\Controller\Adminhtml\User\Role; + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\User\Model\User; +use Magento\Backend\Model\Auth\Session; +use Magento\Framework\Message\MessageInterface; +use Magento\User\Controller\Adminhtml\User\Role\SaveRole; + +/** + * Test class for \Magento\User\Controller\Adminhtml\User\Role. + * + * @magentoAppArea adminhtml + */ +class SaveRoleTest extends \Magento\TestFramework\TestCase\AbstractBackendController +{ + /** + * Test execute method + * + * @magentoDataFixture Magento/User/_files/two_users_with_role.php + * @magentoDbIsolation disabled + */ + public function testExecute() + { + $objectManager = Bootstrap::getObjectManager(); + /** @var \Magento\User\Model\User $currentAdmin */ + $currentAdmin = $objectManager->create(User::class) + ->loadByUsername('user'); + /** @var \Magento\Backend\Model\Auth\Session $authSession */ + $authSession = $objectManager->create(Session::class); + $authSession->setUser($currentAdmin); + $user1Id = $objectManager->create(User::class) + ->loadByUsername('johnAdmin')->getId(); + $user2Id = $objectManager->create(User::class) + ->loadByUsername('annAdmin')->getId(); + + /** @var \Magento\Authorization\Model\RoleFactory $roleFactory */ + $roleFactory = $objectManager->create(\Magento\Authorization\Model\RoleFactory::class); + $role = $roleFactory->create()->load(1); + + /** @var \Magento\AdminGws\Model\Role $gwsRole */ + $gwsRole = $objectManager->get(\Magento\AdminGws\Model\Role::class); + $gwsRole->setAdminRole($role); + $gwsRole->setStoreGroupIds([1]); + + $params = [ + 'role_id' => 1, + 'in_role_user_old'=> $user1Id . '=true&' . $user2Id . '=true', + 'in_role_user'=> $user1Id . '=true&' . $user2Id . '=true', + 'all' => 1, + 'current_password' => 'password1', + 'rolename' => 'Administrators', + ]; + + $post = [ + 'gws_is_all' => 1, + 'gws_store_groups' => ['1'], + ]; + + $this->getRequest()->setParams($params); + $this->getRequest()->setPostValue($post); + + $model = $objectManager->create(SaveRole::class); + $model->execute(); + $this->assertSessionMessages( + $this->equalTo(['You saved the role.']), + MessageInterface::TYPE_SUCCESS + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php b/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php new file mode 100644 index 0000000000000..3b9e9b66427eb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\User\Model\User; + +/** + * Create an admin user with an assigned role + */ + +$objectManager = Bootstrap::getObjectManager(); + +/** @var \Magento\User\Model\ResourceModel\User $model */ +$userResource = $objectManager->create(\Magento\User\Model\ResourceModel\User::class); + +/** @var $user User */ +$user = $objectManager->create(User::class); +$user->setFirstname("John") + ->setIsActive(true) + ->setLastname("Doe") + ->setUsername('johnAdmin') + ->setPassword(\Magento\TestFramework\Bootstrap::ADMIN_PASSWORD) + ->setEmail('JohnadminUser@example.com') + ->setRoleType('G') + ->setResourceId('Magento_Backend::all') + ->setPrivileges("") + ->setAssertId(0) + ->setRoleId(1) + ->setPermission('allow'); + +$userResource->save($user); + +/** @var $user User */ +$user = $objectManager->create(User::class); +$user->setFirstname("Ann") + ->setIsActive(true) + ->setLastname("Doe") + ->setUsername('annAdmin') + ->setPassword(\Magento\TestFramework\Bootstrap::ADMIN_PASSWORD) + ->setEmail('JaneadminUser@example.com') + ->setRoleType('G') + ->setResourceId('Magento_Backend::all') + ->setPrivileges("") + ->setAssertId(0) + ->setRoleId(1) + ->setPermission('allow'); + +$userResource->save($user); diff --git a/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php b/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php new file mode 100644 index 0000000000000..7d7d85c71a994 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\User\Model\User; + +/** + * Create an admin user with an assigned role + */ + +/** @var $user User */ +$user = Bootstrap::getObjectManager()->create(User::class); +$user->loadByUsername('johnAdmin')->delete(); + +/** @var $user User */ +$user = Bootstrap::getObjectManager()->create(User::class); +$user->loadByUsername('annAdmin')->delete(); From 9c617290cf0ae20a2d7b74cb9b2f4dce9204f200 Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Mon, 29 Oct 2018 13:45:45 +0000 Subject: [PATCH 548/812] magento-engcom/import-export-improvements#54: update codee based on phpcs guidelines --- .../Magento/ImportExport/Model/Import/Entity/AbstractEntity.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php index 74e2c5626236c..1fc3257ff2c1e 100644 --- a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php +++ b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php @@ -830,6 +830,8 @@ public function validateData() } /** + * Get error aggregator object + * * @return ProcessingErrorAggregatorInterface */ public function getErrorAggregator() From 6b2a6d0cf51ac5046408ea599426feb468c10510 Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Mon, 29 Oct 2018 13:51:09 +0000 Subject: [PATCH 549/812] magento-engcom/import-export-improvements#93: update based on phpcs ruleset --- .../Magento/ImportExport/Controller/Adminhtml/Import/Start.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index 06b69c512a194..e850f6af86cf9 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -96,7 +96,7 @@ public function execute() $noticeHtml = $this->historyModel->getSummary(); - if($this->historyModel->getErrorFile()) { + if ($this->historyModel->getErrorFile()) { $noticeHtml .= '<div class="import-error-wrapper">' . __('Only the first 100 errors are shown. ') . '<a href="' . $this->createDownloadUrlImportHistoryFile($this->historyModel->getErrorFile()) From b552406f8e1bd7cc5b33b37bdc4e8b757883e0de Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Mon, 29 Oct 2018 16:45:18 +0000 Subject: [PATCH 550/812] magento-engcom/import-export-improvements#134: update file from phpcs feedback --- .../BundleImportExport/Model/Import/Product/Type/Bundle.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php b/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php index 77d331a8b5696..81a47d72602b7 100644 --- a/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php +++ b/app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php @@ -20,6 +20,7 @@ /** * Class Bundle + * * @package Magento\BundleImportExport\Model\Import\Product\Type * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ @@ -349,6 +350,8 @@ protected function populateSelectionTemplate($selection, $optionId, $parentId, $ } /** + * Deprecated method for retrieving mapping between skus and products. + * * @deprecated Misspelled method * @see retrieveProductsByCachedSkus */ @@ -600,6 +603,7 @@ protected function insertOptions() /** * Populate array for insert option values + * * @param array $optionIds * @return array */ From 22594bd6cf742210b2d3b8483702510b25d7fa14 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 29 Oct 2018 11:47:50 -0500 Subject: [PATCH 551/812] MAGETWO-95883: [FT] [Klarna] Failed functional tests --- .../Bundle/Test/Block/Adminhtml/Product/Composite/Configure.xml | 1 - .../Test/Block/Adminhtml/Product/Composite/Configure.xml | 1 - .../Test/Block/Adminhtml/Product/Composite/Configure.xml | 1 - 3 files changed, 3 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/Composite/Configure.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/Composite/Configure.xml index e4c0dce0c5b10..18aedfa97f9eb 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/Composite/Configure.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/Composite/Configure.xml @@ -7,7 +7,6 @@ --> <mapping strict="0"> <fields> - <qty /> <checkbox> <selector>div[contains(@class,"field choice") and label[contains(.,"%product_name%")]]//input</selector> <strategy>xpath</strategy> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Composite/Configure.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Composite/Configure.xml index a66753c2adf23..f7bd155fd2d51 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Composite/Configure.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Composite/Configure.xml @@ -7,7 +7,6 @@ --> <mapping strict="0"> <fields> - <qty /> <attribute> <selector>//div[@class="product-options"]//label[.="%s"]//following-sibling::*//select</selector> <strategy>xpath</strategy> diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Product/Composite/Configure.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Product/Composite/Configure.xml index 7a7a6d2124cb7..2f721f05f5ee8 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Product/Composite/Configure.xml +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Product/Composite/Configure.xml @@ -7,7 +7,6 @@ --> <mapping strict="0"> <fields> - <qty /> <link> <selector>//*[@id="downloadable-links-list"]/*[contains(.,"%link_name%")]//input</selector> <strategy>xpath</strategy> From f38a4fc3e78208a8d63e545bffe81c444a1e09a8 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Mon, 29 Oct 2018 12:58:56 -0500 Subject: [PATCH 552/812] ENGCOM-3292: catalog:images:resize total images count calculates incorrectly #18387: #18807 --- app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php index 068580927b96a..77f67480619e0 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Image.php @@ -12,7 +12,7 @@ use Magento\Framework\DB\Select; use Magento\Framework\App\ResourceConnection; -/* +/** * Class for retrieval of all product images */ class Image From 9043bc9c755268c63db304a499492867d4c91379 Mon Sep 17 00:00:00 2001 From: Matei Purcaru <matei.purcaru@gmail.com> Date: Mon, 29 Oct 2018 19:59:00 +0200 Subject: [PATCH 553/812] magento/graphql-ce#41: Updated global composer.json --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 3f8f0a033c893..ab29199251172 100644 --- a/composer.json +++ b/composer.json @@ -201,6 +201,7 @@ "magento/module-rule": "*", "magento/module-sales": "*", "magento/module-sales-analytics": "*", + "magento/module-sales-graph-ql": "*", "magento/module-sales-inventory": "*", "magento/module-sales-rule": "*", "magento/module-sales-sequence": "*", From 12f839644f71915e165a2804f505a727cd477cfc Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Mon, 29 Oct 2018 12:59:37 -0500 Subject: [PATCH 554/812] ENGCOM-3292: catalog:images:resize total images count calculates incorrectly #18387: #18807 --- .../Test/Unit/Model/ResourceModel/Product/ImageTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php index 1a1eebf30f7f6..cf24998590ae8 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php @@ -187,8 +187,7 @@ protected function getFetchResultCallbackForBatches(int $imagesCount, int $batch protected function getBatchIteratorCallback( \PHPUnit_Framework_MockObject_MockObject $selectMock, int $batchCount - ): \Closure - { + ): \Closure { $getBatchIteratorCallback = function () use ($batchCount, $selectMock): array { $result = []; $count = $batchCount; From 95c3579b9e2b2e6c732d676155953aff3de05702 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Mon, 29 Oct 2018 13:54:28 -0500 Subject: [PATCH 555/812] MAGETWO-95977: Magento 2.3.0-beta18: ReflectionException on Backend -> Stores -> Configuration -> Services -> OAuth page --- .../Integration/etc/adminhtml/system.xml | 2 +- .../System/Config/OauthSectionTest.php | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 dev/tests/integration/testsuite/Magento/Integration/Block/Adminhtml/System/Config/OauthSectionTest.php diff --git a/app/code/Magento/Integration/etc/adminhtml/system.xml b/app/code/Magento/Integration/etc/adminhtml/system.xml index 5abec8efbfdd6..fe80fe105493a 100644 --- a/app/code/Magento/Integration/etc/adminhtml/system.xml +++ b/app/code/Magento/Integration/etc/adminhtml/system.xml @@ -54,7 +54,7 @@ <label>Maximum Login Failures to Lock Out Account</label> <comment>Maximum Number of authentication failures to lock out account.</comment> </field> - <field id="timeout" translate="label" type="text comment" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> + <field id="timeout" translate="label comment" type="text" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1"> <label>Lockout Time (seconds)</label> <comment>Period of time in seconds after which account will be unlocked.</comment> </field> diff --git a/dev/tests/integration/testsuite/Magento/Integration/Block/Adminhtml/System/Config/OauthSectionTest.php b/dev/tests/integration/testsuite/Magento/Integration/Block/Adminhtml/System/Config/OauthSectionTest.php new file mode 100644 index 0000000000000..ac5d8005180b4 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Integration/Block/Adminhtml/System/Config/OauthSectionTest.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + + +namespace Magento\Integration\Block\Adminhtml\System\Config; + +class OauthSectionTest extends \Magento\TestFramework\TestCase\AbstractBackendController +{ + /** + * Checks that OAuth Section in the system config is loaded + */ + public function testOAuthSection() + { + $this->dispatch('backend/admin/system_config/edit/section/oauth/'); + $body = $this->getResponse()->getBody(); + $this->assertContains('id="oauth_access_token_lifetime-head"', $body); + $this->assertContains('id="oauth_cleanup-head"', $body); + $this->assertContains('id="oauth_consumer-head"', $body); + $this->assertContains('id="oauth_authentication_lock-head"', $body); + } +} From 4c25f0e9fbac64044a4bf3cdda17362bac23ac6c Mon Sep 17 00:00:00 2001 From: ayaz <ayaz.mittaqi024@webkul.com> Date: Tue, 30 Oct 2018 10:58:20 +0530 Subject: [PATCH 556/812] issue #18931 fixed. --- app/code/Magento/Catalog/i18n/en_US.csv | 3 ++- app/code/Magento/Checkout/i18n/en_US.csv | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/i18n/en_US.csv b/app/code/Magento/Catalog/i18n/en_US.csv index f2a3ab8f83f24..06c072276f084 100644 --- a/app/code/Magento/Catalog/i18n/en_US.csv +++ b/app/code/Magento/Catalog/i18n/en_US.csv @@ -808,4 +808,5 @@ Details,Details "Product Name or SKU", "Product Name or SKU" "Start typing to find products", "Start typing to find products" "Product with ID: (%1) doesn't exist", "Product with ID: (%1) doesn't exist" -"Category with ID: (%1) doesn't exist", "Category with ID: (%1) doesn't exist" \ No newline at end of file +"Category with ID: (%1) doesn't exist", "Category with ID: (%1) doesn't exist" +"You added product %1 to the <a href=""%2"">comparison list</a>.","You added product %1 to the <a href=""%2"">comparison list</a>." \ No newline at end of file diff --git a/app/code/Magento/Checkout/i18n/en_US.csv b/app/code/Magento/Checkout/i18n/en_US.csv index a6ea2c13579a7..7f2f0b4390321 100644 --- a/app/code/Magento/Checkout/i18n/en_US.csv +++ b/app/code/Magento/Checkout/i18n/en_US.csv @@ -182,3 +182,4 @@ Payment,Payment "Items in Cart","Items in Cart" "Close","Close" "Show Cross-sell Items in the Shopping Cart","Show Cross-sell Items in the Shopping Cart" +"You added %1 to your <a href=""%2"">shopping cart</a>.","You added %1 to your <a href=""%2"">shopping cart</a>." \ No newline at end of file From ac8ca8b619372d1bdbdb9f9b66b6a19907df3a22 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 30 Oct 2018 09:42:00 +0200 Subject: [PATCH 557/812] magento-engcom/magento2ce#2287: Code style fixes --- .../Sales/Model/Order/Creditmemo/Total/Discount.php | 7 ++++++- .../Unit/Model/Order/Creditmemo/Total/DiscountTest.php | 2 +- .../luma/Magento_Checkout/web/css/source/module/_cart.less | 2 +- .../frontend/js/model/cart/estimate-service.test.js | 4 +++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php index 749a12f7d8b55..06bfbcf24daac 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Discount.php @@ -5,9 +5,14 @@ */ namespace Magento\Sales\Model\Order\Creditmemo\Total; +/** + * Discount total calculator + */ class Discount extends AbstractTotal { /** + * Collect discount + * * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo * @return $this * @throws \Magento\Framework\Exception\LocalizedException @@ -34,7 +39,7 @@ public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo) */ if ($baseShippingAmount && $order->getBaseShippingAmount() <= 0) { throw new \Magento\Framework\Exception\LocalizedException( - new \Magento\Framework\Phrase("You can not refund shipping if there is no shipping amount.", []) + __("You can not refund shipping if there is no shipping amount.") ); } if ($baseShippingAmount) { diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php index a9a859ea1b5d6..8a45aa8c7958e 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/DiscountTest.php @@ -292,7 +292,7 @@ public function testCollectNonZeroShipping() ->method('getBaseShippingDiscountAmount'); $this->orderMock->expects($this->once()) ->method('getBaseShippingAmount') - ->willReturn( '0.0000'); + ->willReturn('0.0000'); $this->assertEquals($this->total, $this->total->collect($this->creditmemoMock)); } } diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less index cf7a909889584..58582d344e75a 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less @@ -627,8 +627,8 @@ } &-item-details { - padding-bottom: 35px; display: table-cell; + padding-bottom: 35px; vertical-align: top; white-space: normal; width: 99%; diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js index 31009555bd9f9..7c975bea34abd 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js @@ -152,7 +152,9 @@ define([ }); it('test subscribe when cart data was changed', function () { - mocks['Magento_Customer/js/customer-data'].get('cart')({ data_id: 2 }); + mocks['Magento_Customer/js/customer-data'].get('cart')({ + data_id: 2 + }); expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals).toHaveBeenCalled(); }); }); From 0fe329b6c429e8fd4e84dc8653b66be40cb8296b Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Tue, 30 Oct 2018 09:45:23 +0200 Subject: [PATCH 558/812] ENGCOM-3161: [Forwardport] #4942 and bundle checkbox bug #18520. Fix static tests. --- .../Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php index ed6a4d1ad7209..7c63af0bd0e2e 100644 --- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php +++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php @@ -230,6 +230,8 @@ public function getProduct() } /** + * Get bundle option price title. + * * @param \Magento\Catalog\Model\Product $selection * @param bool $includeContainer * @return string From b7513494fd58447c4418b4f3d29ea40944548ddb Mon Sep 17 00:00:00 2001 From: Kajal Solanki <kajal10395@gmail.com> Date: Mon, 29 Oct 2018 14:21:45 +0530 Subject: [PATCH 559/812] fixed-Global-search icon misaligned-#18913 --- .../web/css/source/module/header/actions-group/_search.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less index 5e65faec60d4e..ddc3cb455402b 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/actions-group/_search.less @@ -153,7 +153,7 @@ background-color: transparent; border: 1px solid transparent; font-size: @search-global-input__font-size; - height: @search-global-input__height; + height: @search-global-input__height + .2; padding: @search-global-input__padding-top @search-global-input__padding-side @search-global-input__padding-bottom; position: absolute; right: 0; From 3895af04b1ddfcae81717b1bf5373ded7e76c7bf Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh <nikita.shcherbatykh@transoftgroup.com> Date: Tue, 30 Oct 2018 09:57:26 +0200 Subject: [PATCH 560/812] MAGETWO-95753: [2.3] Cannot save product with Tier Prices --- .../Controller/Adminhtml/ProductTest.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php index d949993e7ea3c..acec996d0c406 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php @@ -8,6 +8,8 @@ use Magento\Framework\App\Request\DataPersistorInterface; use Magento\Framework\Message\Manager; use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Message\MessageInterface; /** * @magentoAppArea adminhtml @@ -24,7 +26,7 @@ public function testSaveActionWithDangerRequest() $this->dispatch('backend/catalog/product/save'); $this->assertSessionMessages( $this->equalTo(['The product was unable to be saved. Please try again.']), - \Magento\Framework\Message\MessageInterface::TYPE_ERROR + MessageInterface::TYPE_ERROR ); $this->assertRedirect($this->stringContains('/backend/catalog/product/new')); } @@ -44,7 +46,7 @@ public function testSaveActionAndNew() $this->assertRedirect($this->stringStartsWith('http://localhost/index.php/backend/catalog/product/new/')); $this->assertSessionMessages( $this->contains('You saved the product.'), - \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + MessageInterface::TYPE_SUCCESS ); } @@ -71,11 +73,11 @@ public function testSaveActionAndDuplicate() ); $this->assertSessionMessages( $this->contains('You saved the product.'), - \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + MessageInterface::TYPE_SUCCESS ); $this->assertSessionMessages( $this->contains('You duplicated the product.'), - \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + MessageInterface::TYPE_SUCCESS ); } @@ -260,9 +262,7 @@ public function saveActionWithAlreadyExistingUrlKeyDataProvider() * @param array $postData * @param array $tierPrice * @magentoDataFixture Magento/Catalog/_files/product_has_tier_price_show_as_low_as.php - * @magentoAppIsolation enabled * @magentoConfigFixture current_store catalog/price/scope 1 - * @magentoDbIsolation disabled */ public function testSaveActionTierPrice(array $postData, array $tierPrice) { @@ -272,7 +272,7 @@ public function testSaveActionTierPrice(array $postData, array $tierPrice) $this->dispatch('backend/catalog/product/save/id/' . $postData['id']); $this->assertSessionMessages( $this->contains('You saved the product.'), - \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + MessageInterface::TYPE_SUCCESS ); } @@ -349,8 +349,8 @@ public function saveActionTierPriceDataProvider() */ private function getProductData(array $tierPrice) { - $repository = $this->_objectManager->create(\Magento\Catalog\Model\ProductRepository::class); - $product = $repository->get('tier_prices')->getData(); + $productRepositoryInterface = $this->_objectManager->get(ProductRepositoryInterface::class); + $product = $productRepositoryInterface->get('tier_prices')->getData(); $product['tier_price'] = $tierPrice; unset($product['entity_id']); return $product; From 34163dca8d82ee4adbc4387c169215ef8d62d9c2 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Tue, 30 Oct 2018 11:49:19 +0200 Subject: [PATCH 561/812] MAGETWO-95536: [2.3] Admin users are deleted from role upon Role save - moved test --- .../Adminhtml/User/Role/SaveRoleTest.php | 77 ------------------- 1 file changed, 77 deletions(-) delete mode 100644 dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php diff --git a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.php deleted file mode 100644 index 50b28e2bac0a9..0000000000000 --- a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/Role/SaveRoleTest.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\User\Controller\Adminhtml\User\Role; - -use Magento\TestFramework\Helper\Bootstrap; -use Magento\User\Model\User; -use Magento\Backend\Model\Auth\Session; -use Magento\Framework\Message\MessageInterface; -use Magento\User\Controller\Adminhtml\User\Role\SaveRole; - -/** - * Test class for \Magento\User\Controller\Adminhtml\User\Role. - * - * @magentoAppArea adminhtml - */ -class SaveRoleTest extends \Magento\TestFramework\TestCase\AbstractBackendController -{ - /** - * Test execute method - * - * @magentoDataFixture Magento/User/_files/two_users_with_role.php - * @magentoDbIsolation disabled - */ - public function testExecute() - { - $objectManager = Bootstrap::getObjectManager(); - /** @var \Magento\User\Model\User $currentAdmin */ - $currentAdmin = $objectManager->create(User::class) - ->loadByUsername('user'); - /** @var \Magento\Backend\Model\Auth\Session $authSession */ - $authSession = $objectManager->create(Session::class); - $authSession->setUser($currentAdmin); - $user1Id = $objectManager->create(User::class) - ->loadByUsername('johnAdmin')->getId(); - $user2Id = $objectManager->create(User::class) - ->loadByUsername('annAdmin')->getId(); - - /** @var \Magento\Authorization\Model\RoleFactory $roleFactory */ - $roleFactory = $objectManager->create(\Magento\Authorization\Model\RoleFactory::class); - $role = $roleFactory->create()->load(1); - - /** @var \Magento\AdminGws\Model\Role $gwsRole */ - $gwsRole = $objectManager->get(\Magento\AdminGws\Model\Role::class); - $gwsRole->setAdminRole($role); - $gwsRole->setStoreGroupIds([1]); - - $params = [ - 'role_id' => 1, - 'in_role_user_old'=> $user1Id . '=true&' . $user2Id . '=true', - 'in_role_user'=> $user1Id . '=true&' . $user2Id . '=true', - 'all' => 1, - 'current_password' => 'password1', - 'rolename' => 'Administrators', - ]; - - $post = [ - 'gws_is_all' => 1, - 'gws_store_groups' => ['1'], - ]; - - $this->getRequest()->setParams($params); - $this->getRequest()->setPostValue($post); - - $model = $objectManager->create(SaveRole::class); - $model->execute(); - $this->assertSessionMessages( - $this->equalTo(['You saved the role.']), - MessageInterface::TYPE_SUCCESS - ); - } -} From fbca4dd480841013d112118e5417a8ed4c7e8a69 Mon Sep 17 00:00:00 2001 From: Sven Reichel <github-sr@hotmail.com> Date: Tue, 30 Oct 2018 11:03:02 +0100 Subject: [PATCH 562/812] Fixed annotations - Magento\Catalog\Model\ResourceModel\Product\Collection::addAttributeToFilter() - Magento\Quote\Model\QuoteAddress::setCollectShippingRates() --- .../Catalog/Model/ResourceModel/Product/Collection.php | 2 +- app/code/Magento/Quote/Model/Quote/Address.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 5afac59b25db6..14ae38667d873 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -1534,7 +1534,7 @@ public function addPriceData($customerGroupId = null, $websiteId = null) /** * Add attribute to filter * - * @param \Magento\Eav\Model\Entity\Attribute\AbstractAttribute|string $attribute + * @param \Magento\Eav\Model\Entity\Attribute\AbstractAttribute|string|array $attribute * @param array $condition * @param string $joinType * @return $this diff --git a/app/code/Magento/Quote/Model/Quote/Address.php b/app/code/Magento/Quote/Model/Quote/Address.php index 3eb5d68885035..f34cfbbf5fd26 100644 --- a/app/code/Magento/Quote/Model/Quote/Address.php +++ b/app/code/Magento/Quote/Model/Quote/Address.php @@ -28,8 +28,8 @@ * @method Address setAddressType(string $value) * @method int getFreeShipping() * @method Address setFreeShipping(int $value) - * @method int getCollectShippingRates() - * @method Address setCollectShippingRates(int $value) + * @method bool getCollectShippingRates() + * @method Address setCollectShippingRates(bool $value) * @method Address setShippingMethod(string $value) * @method string getShippingDescription() * @method Address setShippingDescription(string $value) From 42b235827941fb1713a360edcdbeebb0a95a35d4 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 30 Oct 2018 11:45:50 +0100 Subject: [PATCH 563/812] Consolidated cart address information provider --- .../Resolver/Address/AddressDataProvider.php | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php index d401f296cb465..80fe973c4e449 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php @@ -10,6 +10,7 @@ use Magento\Framework\Api\ExtensibleDataObjectConverter; use Magento\Quote\Api\Data\AddressInterface; use Magento\Quote\Api\Data\CartInterface; +use Magento\Quote\Model\Quote\Address as QuoteAddress; /** * Class AddressDataProvider @@ -49,22 +50,45 @@ public function getCartAddresses(CartInterface $cart): array if ($shippingAddress) { $shippingData = $this->dataObjectConverter->toFlatArray($shippingAddress, [], AddressInterface::class); $shippingData['address_type'] = 'SHIPPING'; - $shippingData['selected_shipping_method'] = [ - 'code' => $shippingAddress->getShippingMethod(), - 'label' => $shippingAddress->getShippingDescription(), - 'free_shipping' => $shippingAddress->getFreeShipping(), - ]; - $shippingData['items_weight'] = $shippingAddress->getWeight(); - $shippingData['customer_notes'] = $shippingAddress->getCustomerNotes(); - $addressData[] = $shippingData; + $addressData[] = array_merge($shippingData, $this->extractAddressData($shippingAddress)); } if ($billingAddress) { $billingData = $this->dataObjectConverter->toFlatArray($billingAddress, [], AddressInterface::class); $billingData['address_type'] = 'BILLING'; - $addressData[] = $billingData; + $addressData[] = array_merge($billingData, $this->extractAddressData($billingAddress)); } return $addressData; } + + /** + * Extract the necessary address fields from address model + * + * @param QuoteAddress $address + * @return array + */ + private function extractAddressData(QuoteAddress $address): array + { + $addressData = [ + 'country' => [ + 'code' => $address->getCountryId(), + 'label' => $address->getCountry() + ], + 'region' => [ + 'code' => $address->getRegionCode(), + 'label' => $address->getRegion() + ], + 'street' => $address->getStreet(), + 'selected_shipping_method' => [ + 'code' => $address->getShippingMethod(), + 'label' => $address->getShippingDescription(), + 'free_shipping' => $address->getFreeShipping(), + ], + 'items_weight' => $address->getWeight(), + 'customer_notes' => $address->getCustomerNotes() + ]; + + return $addressData; + } } From 7e42eba3b9a2003e227404b33a29b728ae48a62a Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Tue, 30 Oct 2018 12:57:31 +0200 Subject: [PATCH 564/812] MAGETWO-95536: [2.3] Admin users are deleted from role upon Role save - moved files --- .../User/_files/two_users_with_role.php | 52 ------------------- .../_files/two_users_with_role_rollback.php | 21 -------- 2 files changed, 73 deletions(-) delete mode 100644 dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php delete mode 100644 dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php b/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php deleted file mode 100644 index 3b9e9b66427eb..0000000000000 --- a/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\TestFramework\Helper\Bootstrap; -use Magento\User\Model\User; - -/** - * Create an admin user with an assigned role - */ - -$objectManager = Bootstrap::getObjectManager(); - -/** @var \Magento\User\Model\ResourceModel\User $model */ -$userResource = $objectManager->create(\Magento\User\Model\ResourceModel\User::class); - -/** @var $user User */ -$user = $objectManager->create(User::class); -$user->setFirstname("John") - ->setIsActive(true) - ->setLastname("Doe") - ->setUsername('johnAdmin') - ->setPassword(\Magento\TestFramework\Bootstrap::ADMIN_PASSWORD) - ->setEmail('JohnadminUser@example.com') - ->setRoleType('G') - ->setResourceId('Magento_Backend::all') - ->setPrivileges("") - ->setAssertId(0) - ->setRoleId(1) - ->setPermission('allow'); - -$userResource->save($user); - -/** @var $user User */ -$user = $objectManager->create(User::class); -$user->setFirstname("Ann") - ->setIsActive(true) - ->setLastname("Doe") - ->setUsername('annAdmin') - ->setPassword(\Magento\TestFramework\Bootstrap::ADMIN_PASSWORD) - ->setEmail('JaneadminUser@example.com') - ->setRoleType('G') - ->setResourceId('Magento_Backend::all') - ->setPrivileges("") - ->setAssertId(0) - ->setRoleId(1) - ->setPermission('allow'); - -$userResource->save($user); diff --git a/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php b/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php deleted file mode 100644 index 7d7d85c71a994..0000000000000 --- a/dev/tests/integration/testsuite/Magento/User/_files/two_users_with_role_rollback.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\TestFramework\Helper\Bootstrap; -use Magento\User\Model\User; - -/** - * Create an admin user with an assigned role - */ - -/** @var $user User */ -$user = Bootstrap::getObjectManager()->create(User::class); -$user->loadByUsername('johnAdmin')->delete(); - -/** @var $user User */ -$user = Bootstrap::getObjectManager()->create(User::class); -$user->loadByUsername('annAdmin')->delete(); From 1cfa17f2de57c9a095f248d8e9aa81e5fa3ca35b Mon Sep 17 00:00:00 2001 From: Matei Purcaru <matei.purcaru@gmail.com> Date: Tue, 30 Oct 2018 13:24:01 +0200 Subject: [PATCH 565/812] magento/graphql-ce#41: Updated composer.lock hash --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 1d101c8aaaf15..bc2160a2b18bd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d6640ddfd342feceaec44c406c056f57", + "content-hash": "edf8aa5e66649f1a221f027a3600d41e", "packages": [ { "name": "braintree/braintree_php", From 61d81a8e07b627eb7f3850529767e1427461f52b Mon Sep 17 00:00:00 2001 From: Andrii Dimov <adimov@adobe.com> Date: Fri, 12 Oct 2018 20:59:40 +0300 Subject: [PATCH 566/812] MAGETWO-95651: Narrow number of top menu cache versions --- app/code/Magento/Theme/Block/Html/Topmenu.php | 4 +--- app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Theme/Block/Html/Topmenu.php b/app/code/Magento/Theme/Block/Html/Topmenu.php index 0dca0f8606a8c..6961a89b41e08 100644 --- a/app/code/Magento/Theme/Block/Html/Topmenu.php +++ b/app/code/Magento/Theme/Block/Html/Topmenu.php @@ -369,9 +369,7 @@ public function getIdentities() */ public function getCacheKeyInfo() { - $keyInfo = parent::getCacheKeyInfo(); - $keyInfo[] = $this->getUrl('*/*/*', ['_current' => true, '_query' => '']); - return $keyInfo; + return parent::getCacheKeyInfo(); } /** diff --git a/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php b/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php index 91c3ce47fc8b8..023c741492752 100644 --- a/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php +++ b/app/code/Magento/Theme/Test/Unit/Block/Html/TopmenuTest.php @@ -189,7 +189,6 @@ public function testGetCacheKeyInfo() $treeFactory = $this->createMock(\Magento\Framework\Data\TreeFactory::class); $topmenu = new Topmenu($this->context, $nodeFactory, $treeFactory); - $this->urlBuilder->expects($this->once())->method('getUrl')->with('*/*/*')->willReturn('123'); $this->urlBuilder->expects($this->once())->method('getBaseUrl')->willReturn('baseUrl'); $store = $this->getMockBuilder(\Magento\Store\Model\Store::class) ->disableOriginalConstructor() @@ -199,7 +198,7 @@ public function testGetCacheKeyInfo() $this->storeManager->expects($this->once())->method('getStore')->willReturn($store); $this->assertEquals( - ['BLOCK_TPL', '321', null, 'base_url' => 'baseUrl', 'template' => null, '123'], + ['BLOCK_TPL', '321', null, 'base_url' => 'baseUrl', 'template' => null], $topmenu->getCacheKeyInfo() ); } From fcb3d675ea3df97f8935cc5a560a396ac9ae7db2 Mon Sep 17 00:00:00 2001 From: "Lopukhov, Stanislav" <lopukhov@adobe.com> Date: Tue, 30 Oct 2018 14:31:32 +0200 Subject: [PATCH 567/812] MAGETWO-95651: Narrow number of top menu cache versions --- app/code/Magento/Theme/Block/Html/Topmenu.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/code/Magento/Theme/Block/Html/Topmenu.php b/app/code/Magento/Theme/Block/Html/Topmenu.php index 6961a89b41e08..242947d19b321 100644 --- a/app/code/Magento/Theme/Block/Html/Topmenu.php +++ b/app/code/Magento/Theme/Block/Html/Topmenu.php @@ -361,17 +361,6 @@ public function getIdentities() return $this->identities; } - /** - * Get cache key informative items - * - * @return array - * @since 100.1.0 - */ - public function getCacheKeyInfo() - { - return parent::getCacheKeyInfo(); - } - /** * Get tags array for saving cache * From e32808beebefcbf43d541bcf37aa96460bee519b Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Tue, 30 Oct 2018 08:57:34 -0400 Subject: [PATCH 568/812] Extracted websiteString property to local variable --- .../Import/AdvancedPricing/Validator/WebsiteTest.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php index 41ac72bd8dacc..d78c4f5e61af3 100644 --- a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php +++ b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php @@ -25,11 +25,6 @@ class WebsiteTest extends \PHPUnit\Framework\TestCase */ protected $website; - /** - * @var \Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator\Website|\PHPUnit_Framework_MockObject_MockObject - */ - protected $websiteString; - protected function setUp() { $this->webSiteModel = $this->getMockBuilder(\Magento\Store\Model\Website::class) @@ -108,13 +103,13 @@ public function testGetAllWebsitesValue() $this->webSiteModel->expects($this->once())->method('getBaseCurrency')->willReturn($currency); $expectedResult = AdvancedPricing::VALUE_ALL_WEBSITES . ' [' . $currencyCode . ']'; - $this->websiteString = $this->getMockBuilder( + $websiteString = $this->getMockBuilder( \Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator\Website::class ) ->setMethods(['_clearMessages', '_addMessages']) ->setConstructorArgs([$this->storeResolver, $this->webSiteModel]) ->getMock(); - $result = $this->websiteString->getAllWebsitesValue(); + $result = $websiteString->getAllWebsitesValue(); $this->assertEquals($expectedResult, $result); } From 2f5fc9742ed261a0e3440db0ce87963f502644e5 Mon Sep 17 00:00:00 2001 From: Sven Reichel <github-sr@hotmail.com> Date: Tue, 30 Oct 2018 14:11:05 +0100 Subject: [PATCH 569/812] Fixed annotations - Magento\Customer\Model\Address\AbstractAddress::getCountry() - Magento\Customer\Model\Address\AbstractAddress::getCountryId() --- app/code/Magento/Customer/Model/Address/AbstractAddress.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php index 6408276630c3f..3ee284a705b16 100644 --- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php +++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php @@ -23,7 +23,7 @@ * @method string getFirstname() * @method string getMiddlename() * @method string getLastname() - * @method int getCountryId() + * @method string getCountryId() * @method string getCity() * @method string getTelephone() * @method string getCompany() @@ -425,7 +425,7 @@ public function getRegionId() } /** - * @return int + * @return string */ public function getCountry() { From d0c4c6411343a0dbebd2e3a2b0aa8d5be9a94ac1 Mon Sep 17 00:00:00 2001 From: Max Almonte <maxalmonte14@hotmail.com> Date: Tue, 30 Oct 2018 09:14:07 -0400 Subject: [PATCH 570/812] Fixed property type in docblock --- .../Magento/CustomerImportExport/Model/Import/Address.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CustomerImportExport/Model/Import/Address.php b/app/code/Magento/CustomerImportExport/Model/Import/Address.php index 9ba50738ebc1a..a8ca6969a6ea1 100644 --- a/app/code/Magento/CustomerImportExport/Model/Import/Address.php +++ b/app/code/Magento/CustomerImportExport/Model/Import/Address.php @@ -104,9 +104,9 @@ class Address extends AbstractCustomer /** * Region collection instance * - * @var string + * @var \Magento\Directory\Model\ResourceModel\Region\Collection */ - protected $_regionCollection; + private $_regionCollection; /** * Countries and regions From c95ce3ca53529c1a1e38f2ec5b187c64f45029e6 Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Mon, 11 Dec 2017 14:11:02 +0200 Subject: [PATCH 571/812] magento/magento2#18387: catalog:images:resize fails to process all images -> Possible underlying Magento/Framework/DB/Query/Generator issue - fix code style; --- .../Model/ResourceModel/Product/ImageTest.php | 62 ++++++++++++------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php index 1a1eebf30f7f6..4fce12dc2de89 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/ImageTest.php @@ -13,6 +13,8 @@ use Magento\Framework\DB\Select; use Magento\Framework\App\ResourceConnection; use Magento\Catalog\Model\ResourceModel\Product\Gallery; +use PHPUnit_Framework_MockObject_MockObject as MockObject; +use Magento\Framework\DB\Query\BatchIteratorInterface; class ImageTest extends \PHPUnit\Framework\TestCase { @@ -22,34 +24,37 @@ class ImageTest extends \PHPUnit\Framework\TestCase protected $objectManager; /** - * @var AdapterInterface | \PHPUnit_Framework_MockObject_MockObject + * @var AdapterInterface | MockObject */ protected $connectionMock; /** - * @var Generator | \PHPUnit_Framework_MockObject_MockObject + * @var Generator | MockObject */ protected $generatorMock; /** - * @var ResourceConnection | \PHPUnit_Framework_MockObject_MockObject + * @var ResourceConnection | MockObject */ protected $resourceMock; protected function setUp(): void { - $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->objectManager = + new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->connectionMock = $this->createMock(AdapterInterface::class); $this->resourceMock = $this->createMock(ResourceConnection::class); - $this->resourceMock->method('getConnection')->willReturn($this->connectionMock); - $this->resourceMock->method('getTableName')->willReturnArgument(0); + $this->resourceMock->method('getConnection') + ->willReturn($this->connectionMock); + $this->resourceMock->method('getTableName') + ->willReturnArgument(0); $this->generatorMock = $this->createMock(Generator::class); } /** - * @return \PHPUnit_Framework_MockObject_MockObject + * @return MockObject */ - protected function getVisibleImagesSelectMock(): \PHPUnit_Framework_MockObject_MockObject + protected function getVisibleImagesSelectMock(): MockObject { $selectMock = $this->getMockBuilder(Select::class) ->disableOriginalConstructor() @@ -105,7 +110,10 @@ public function testGetCountAllProductImages(int $imagesCount): void ] ); - $this->assertSame($imagesCount, $imageModel->getCountAllProductImages()); + $this->assertSame( + $imagesCount, + $imageModel->getCountAllProductImages() + ); } /** @@ -113,8 +121,10 @@ public function testGetCountAllProductImages(int $imagesCount): void * @param int $batchSize * @dataProvider dataProvider */ - public function testGetAllProductImages(int $imagesCount, int $batchSize): void - { + public function testGetAllProductImages( + int $imagesCount, + int $batchSize + ): void { $this->connectionMock->expects($this->once()) ->method('select') ->willReturn($this->getVisibleImagesSelectMock()); @@ -125,7 +135,7 @@ public function testGetAllProductImages(int $imagesCount, int $batchSize): void ->method('fetchAll') ->will($this->returnCallback($fetchResultsCallback)); - /** @var Select | \PHPUnit_Framework_MockObject_MockObject $selectMock */ + /** @var Select | MockObject $selectMock */ $selectMock = $this->getMockBuilder(Select::class) ->disableOriginalConstructor() ->getMock(); @@ -136,8 +146,12 @@ public function testGetAllProductImages(int $imagesCount, int $batchSize): void 'value_id', $selectMock, $batchSize, - \Magento\Framework\DB\Query\BatchIteratorInterface::NON_UNIQUE_FIELD_ITERATOR - )->will($this->returnCallback($this->getBatchIteratorCallback($selectMock, $batchCount))); + BatchIteratorInterface::NON_UNIQUE_FIELD_ITERATOR + )->will( + $this->returnCallback( + $this->getBatchIteratorCallback($selectMock, $batchCount) + ) + ); $imageModel = $this->objectManager->getObject( Image::class, @@ -156,10 +170,13 @@ public function testGetAllProductImages(int $imagesCount, int $batchSize): void * @param int $batchSize * @return \Closure */ - protected function getFetchResultCallbackForBatches(int $imagesCount, int $batchSize): \Closure - { + protected function getFetchResultCallbackForBatches( + int $imagesCount, + int $batchSize + ): \Closure { $fetchResultsCallback = function () use (&$imagesCount, $batchSize) { - $batchSize = ($imagesCount >= $batchSize) ? $batchSize : $imagesCount; + $batchSize = + ($imagesCount >= $batchSize) ? $batchSize : $imagesCount; $imagesCount -= $batchSize; $getFetchResults = function ($batchSize): array { @@ -180,16 +197,15 @@ protected function getFetchResultCallbackForBatches(int $imagesCount, int $batch } /** - * @param Select | \PHPUnit_Framework_MockObject_MockObject $selectMock + * @param Select | MockObject $selectMock * @param int $batchCount * @return \Closure */ protected function getBatchIteratorCallback( - \PHPUnit_Framework_MockObject_MockObject $selectMock, + MockObject $selectMock, int $batchCount - ): \Closure - { - $getBatchIteratorCallback = function () use ($batchCount, $selectMock): array { + ): \Closure { + $iteratorCallback = function () use ($batchCount, $selectMock): array { $result = []; $count = $batchCount; while ($count) { @@ -200,7 +216,7 @@ protected function getBatchIteratorCallback( return $result; }; - return $getBatchIteratorCallback; + return $iteratorCallback; } /** From 1e304992e950945394ea331004fe700b6173a909 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 30 Oct 2018 15:46:55 +0200 Subject: [PATCH 572/812] MAGETWO-94835: Automate with MFTF Filter shared catalogs by 'Created By' field --- .../Mftf/Section/CheckoutShippingSection.xml | 1 + .../AdminDeleteUserActionGroup.xml | 28 +++++++++++++++++++ .../Magento/User/Test/Mftf/Data/UserData.xml | 14 ++++++++++ .../User/Test/Mftf/Metadata/user-meta.xml | 5 +++- 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteUserActionGroup.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index ff7f8995c0681..fb9a79bc93865 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -33,5 +33,6 @@ <element name="defaultShipping" type="button" selector=".billing-address-details"/> <element name="state" type="button" selector="//*[text()='Alabama']"/> <element name="stateInput" type="input" selector="input[name=region]"/> + <element name="editActiveAddress" type="button" selector="//div[@class='shipping-address-item selected-item']//span[text()='Edit']" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteUserActionGroup.xml b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteUserActionGroup.xml new file mode 100644 index 0000000000000..70c0a772ec341 --- /dev/null +++ b/app/code/Magento/User/Test/Mftf/ActionGroup/AdminDeleteUserActionGroup.xml @@ -0,0 +1,28 @@ +<?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="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminDeleteCustomUserActionGroup"> + <arguments> + <argument name="user"/> + </arguments> + <amOnPage url="{{AdminUsersPage.url}}" stepKey="navigateToUserGrid" /> + <fillField selector="{{AdminUserGridSection.usernameFilterTextField}}" userInput="{{user.username}}" stepKey="enterUserName" /> + <click selector="{{AdminUserGridSection.searchButton}}" stepKey="clickSearch" /> + <waitForPageLoad stepKey="waitForGridToLoad"/> + <see selector="{{AdminUserGridSection.usernameInFirstRow}}" userInput="{{user.username}}" stepKey="seeUser" /> + <click selector="{{AdminUserGridSection.searchResultFirstRow}}" stepKey="openUserEdit"/> + <waitForPageLoad stepKey="waitForUserEditPageLoad"/> + <fillField selector="{{AdminEditUserSection.currentPasswordField}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}" stepKey="enterThePassword" /> + <click selector="{{AdminMainActionsSection.delete}}" stepKey="deleteUser"/> + <waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForConfirmModal"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmDelete"/> + <waitForPageLoad stepKey="waitForSave" /> + <see selector="{{AdminMessagesSection.success}}" userInput="You deleted the user." stepKey="seeUserDeleteMessage"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/User/Test/Mftf/Data/UserData.xml b/app/code/Magento/User/Test/Mftf/Data/UserData.xml index 03ae3dba21840..80c1cc3022964 100644 --- a/app/code/Magento/User/Test/Mftf/Data/UserData.xml +++ b/app/code/Magento/User/Test/Mftf/Data/UserData.xml @@ -18,4 +18,18 @@ <data key="lastName">Smith</data> <data key="password">admin123</data> </entity> + <entity name="Admin3" type="user"> + <data key="username" unique="suffix">admin3</data> + <data key="firstname">admin3</data> + <data key="lastname">admin3</data> + <data key="email" unique="prefix">admin3WebUser@example.com</data> + <data key="password">123123q</data> + <data key="password_confirmation">123123q</data> + <data key="interface_local">en_US</data> + <data key="is_active">true</data> + <data key="current_password">123123q</data> + <array key="roles"> + <item>1</item> + </array> + </entity> </entities> diff --git a/app/code/Magento/User/Test/Mftf/Metadata/user-meta.xml b/app/code/Magento/User/Test/Mftf/Metadata/user-meta.xml index 2e1e5f6f5a97d..1ee29be6b3d76 100644 --- a/app/code/Magento/User/Test/Mftf/Metadata/user-meta.xml +++ b/app/code/Magento/User/Test/Mftf/Metadata/user-meta.xml @@ -6,7 +6,7 @@ */ --> <operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> <operation name="CreateUser" dataType="user" type="create" auth="adminFormKey" url="/admin/user/save/" method="POST" successRegex="/messages-message-success/" returnRegex="" > <contentType>application/x-www-form-urlencoded</contentType> @@ -19,5 +19,8 @@ <field key="interface_locale">string</field> <field key="is_active">boolean</field> <field key="current_password">string</field> + <array key="roles"> + <value>string</value> + </array> </operation> </operations> From 152b0924d652de96bb49a93959bb3b304e2601ba Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi <yevhenii.dumskyi@gmail.com> Date: Tue, 30 Oct 2018 16:34:52 +0200 Subject: [PATCH 573/812] Fix Notice and Exception while adding image to product programmatically --- .../Model/Product/Gallery/Processor.php | 24 +++++++++++++++---- composer.json | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index c6c7fbda7e9ec..225c502830695 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -6,6 +6,7 @@ namespace Magento\Catalog\Model\Product\Gallery; +use Magento\Framework\Api\Data\ImageContentInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Filesystem\DriverInterface; @@ -183,6 +184,13 @@ public function addImage( $attrCode = $this->getAttribute()->getAttributeCode(); $mediaGalleryData = $product->getData($attrCode); $position = 0; + + $absoluteFilePath = $this->mediaDirectory->getAbsolutePath($file); + $imageMimeType = mime_content_type($absoluteFilePath); + $imageContent = file_get_contents($absoluteFilePath); + $imageBase64 = base64_encode($imageContent); + $imageName = pathinfo($destinationFile, PATHINFO_FILENAME); + if (!is_array($mediaGalleryData)) { $mediaGalleryData = ['images' => []]; } @@ -195,11 +203,19 @@ public function addImage( $position++; $mediaGalleryData['images'][] = [ - 'file' => $fileName, - 'position' => $position, + 'file' => $fileName, + 'position' => $position, + 'label' => '', + 'disabled' => (int)$exclude, 'media_type' => 'image', - 'label' => '', - 'disabled' => (int)$exclude, + 'types' => $mediaAttribute, + 'content' => [ + 'data' => [ + ImageContentInterface::NAME => $imageName, + ImageContentInterface::BASE64_ENCODED_DATA => $imageBase64, + ImageContentInterface::TYPE => $imageMimeType, + ] + ] ]; $product->setData($attrCode, $mediaGalleryData); diff --git a/composer.json b/composer.json index e2a646275d98b..68bf1f1d8a8b0 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,7 @@ "ext-xsl": "*", "ext-zip": "*", "lib-libxml": "*", + "ext-fileinfo": "*", "braintree/braintree_php": "3.35.0", "colinmollenhour/cache-backend-file": "~1.4.1", "colinmollenhour/cache-backend-redis": "1.10.5", From 124164e3a2e667e40814af444d0d0cf68b952867 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 30 Oct 2018 16:46:36 +0200 Subject: [PATCH 574/812] magento-engcom/magento2ce#2287: Code style fixes --- .../Checkout/frontend/js/model/cart/estimate-service.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js index 7c975bea34abd..ce9c98c9d2560 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/cart/estimate-service.test.js @@ -153,7 +153,7 @@ define([ it('test subscribe when cart data was changed', function () { mocks['Magento_Customer/js/customer-data'].get('cart')({ - data_id: 2 + dataId: 2 }); expect(mocks['Magento_Checkout/js/model/cart/totals-processor/default'].estimateTotals).toHaveBeenCalled(); }); From 898d2a507a283c15af63dedf2c837bbba03ba89c Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Tue, 30 Oct 2018 17:52:51 +0300 Subject: [PATCH 575/812] MAGETWO-91650: Translation not working for product alerts - Replacing name with referenceId --- app/code/Magento/ProductAlert/etc/db_schema.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ProductAlert/etc/db_schema.xml b/app/code/Magento/ProductAlert/etc/db_schema.xml index c6dd8db321b54..820a8029e2d95 100644 --- a/app/code/Magento/ProductAlert/etc/db_schema.xml +++ b/app/code/Magento/ProductAlert/etc/db_schema.xml @@ -52,7 +52,7 @@ <index referenceId="PRODUCT_ALERT_PRICE_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="PRODUCT_ALERT_PRICE_STORE_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_PRICE_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> @@ -99,7 +99,7 @@ <index referenceId="PRODUCT_ALERT_STOCK_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index name="PRODUCT_ALERT_STOCK_STORE_ID" indexType="btree"> + <index referenceId="PRODUCT_ALERT_STOCK_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> From fab32c6f68410e507b721206a8902ea77d1ce506 Mon Sep 17 00:00:00 2001 From: David Manners <dmanners87@gmail.com> Date: Tue, 30 Oct 2018 15:32:35 +0000 Subject: [PATCH 576/812] Fix PHPCS check for "Short description must start with a capital letter" --- .../Magento/CustomerImportExport/Model/Import/Address.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CustomerImportExport/Model/Import/Address.php b/app/code/Magento/CustomerImportExport/Model/Import/Address.php index a8ca6969a6ea1..7a1a09efaa7b6 100644 --- a/app/code/Magento/CustomerImportExport/Model/Import/Address.php +++ b/app/code/Magento/CustomerImportExport/Model/Import/Address.php @@ -788,7 +788,7 @@ public static function getDefaultAddressAttributeMapping() } /** - * check if address for import is empty (for customer composite mode) + * Check if address for import is empty (for customer composite mode) * * @param array $rowData * @return array @@ -947,7 +947,7 @@ protected function _checkRowDuplicate($customerId, $addressId) } /** - * set customer attributes + * Set customer attributes * * @param array $customerAttributes * @return $this From 052d0cc0dda65fa2a014cd0c6a3925b2d14c3f12 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Tue, 30 Oct 2018 13:20:37 -0500 Subject: [PATCH 577/812] MAGETWO-95773: Credit memo is created instead of returning error via invoice refund API for Bundle product - add error message for incorrect product items --- .../Item/Validation/CreationQuantityValidator.php | 4 ++++ app/code/Magento/Sales/Model/Order/ItemRepository.php | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php index 0c2adfff80a2b..fdc5e2658b9ed 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php @@ -53,6 +53,10 @@ public function validate($entity) return [__('The creditmemo contains product item that is not part of the original order.')]; } + if ($orderItem->isDummy()) { + return [__('The creditmemo contains incorrect product items.')]; + } + if (!$this->isQtyAvailable($orderItem, $entity->getQty())) { return [__('The quantity to refund must not be greater than the unrefunded quantity.')]; } diff --git a/app/code/Magento/Sales/Model/Order/ItemRepository.php b/app/code/Magento/Sales/Model/Order/ItemRepository.php index 7916eb9db2b80..2ea9831336cc2 100644 --- a/app/code/Magento/Sales/Model/Order/ItemRepository.php +++ b/app/code/Magento/Sales/Model/Order/ItemRepository.php @@ -228,6 +228,12 @@ private function addParentItem(OrderItemInterface $orderItem) { if ($parentId = $orderItem->getParentItemId()) { $orderItem->setParentItem($this->get($parentId)); + } else { + foreach ($orderItem->getOrder()->getAllItems() as $item) { + if($item->getParentItemId() === $orderItem->getItemId()) { + $item->setParentItem($orderItem); + } + } } } From 54f4802d5a9ef58418e395e8d12ab4931907d6eb Mon Sep 17 00:00:00 2001 From: larsroettig <l.roettig@techdivision.com> Date: Tue, 30 Oct 2018 21:32:40 +0100 Subject: [PATCH 578/812] #18956 Fixes for set root_category_id --- .../Magento/Store/Model/Config/Importer/Processor/Create.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php index 513ba04802985..3142955ac5988 100644 --- a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php +++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php @@ -177,8 +177,8 @@ private function createGroups(array $items, array $data) ); $group = $this->groupFactory->create(); - $group->setData($groupData); $group->setRootCategoryId(0); + $group->setData($groupData); $group->getResource()->save($group); $group->getResource()->addCommitCallback(function () use ($data, $group, $website) { From d64351b30bf3ab566d42a4acf312c9b1a08045da Mon Sep 17 00:00:00 2001 From: Ayaz Mittaqi <ayaz.mittaqi024@webkul.com> Date: Wed, 31 Oct 2018 03:20:22 +0530 Subject: [PATCH 579/812] removed old string from catalog translation file --- app/code/Magento/Catalog/i18n/en_US.csv | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/i18n/en_US.csv b/app/code/Magento/Catalog/i18n/en_US.csv index 06c072276f084..ed27dfd646cb2 100644 --- a/app/code/Magento/Catalog/i18n/en_US.csv +++ b/app/code/Magento/Catalog/i18n/en_US.csv @@ -233,7 +233,6 @@ Products,Products "This attribute set no longer exists.","This attribute set no longer exists." "You saved the attribute set.","You saved the attribute set." "Something went wrong while saving the attribute set.","Something went wrong while saving the attribute set." -"You added product %1 to the comparison list.","You added product %1 to the comparison list." "You cleared the comparison list.","You cleared the comparison list." "Something went wrong clearing the comparison list.","Something went wrong clearing the comparison list." "You removed product %1 from the comparison list.","You removed product %1 from the comparison list." From b135ec9c010f6a06649da1a30bf7778a52988a03 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 31 Oct 2018 10:43:01 +0300 Subject: [PATCH 580/812] MAGETWO-91609: Problems with operator more/less in the "catalog Products List" widget - Fix unit test --- .../Test/Unit/Model/Condition/Sql/BuilderTest.php | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php b/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php index 5d18ccef17e54..13bba8a6a28ab 100644 --- a/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php +++ b/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php @@ -119,13 +119,12 @@ public function testAttachConditionAsHtmlToCollection() \Magento\Eav\Model\Entity\Collection\AbstractCollection::class, [ 'getResource', - 'getSelect', - 'getStoreId', - 'getDefaultStoreId', + 'getSelect' ] ); - $combine = $this->createPartialMock(\Magento\Rule\Model\Condition\Combine::class, + $combine = $this->createPartialMock( + \Magento\Rule\Model\Condition\Combine::class, [ 'getConditions', 'getValue', @@ -153,14 +152,6 @@ public function testAttachConditionAsHtmlToCollection() ->method('getResource') ->will($this->returnValue($resource)); - $collection->expects($this->once()) - ->method('getStoreId') - ->willReturn(1); - - $collection->expects($this->once()) - ->method('getDefaultStoreId') - ->willReturn(1); - $resource->expects($this->once()) ->method('getConnection') ->will($this->returnValue($connection)); From 8641218ebe978623fb1aa731544b76be99003448 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 31 Oct 2018 11:09:20 +0200 Subject: [PATCH 581/812] MAGETWO-95299: Ability to upload PDP images without compression and downsizing --- .../view/adminhtml/templates/browser/content/uploader.phtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml index df0a74c48ac23..414d42cb45382 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml @@ -19,9 +19,9 @@ foreach ($filters as $media_type) { $resizeConfig = $block->getImageUploadConfigData()->getIsResizeEnabled() ? "{action: 'resize', maxWidth: " - . $block->getImageUploadMaxWidth() + . $block->escapeHtml($block->getImageUploadMaxWidth()) . ", maxHeight: " - . $block->getImageUploadMaxHeight() + . $block->escapeHtml($block->getImageUploadMaxHeight()) . "}" : "{action: 'resize'}"; ?> @@ -153,7 +153,7 @@ require([ fileTypes: /^image\/(gif|jpeg|png)$/, maxFileSize: <?= (int) $block->getFileSizeService()->getMaxFileSize() ?> * 10 }, - <?= $block->escapeHtml($resizeConfig) ?>, + <?= /* @noEscape */ $resizeConfig ?>, { action: 'save' }] From 7fd52e7ea8f7c7f77702d1b7a4665e715eee1ac3 Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi <yevhenii.dumskyi@gmail.com> Date: Wed, 31 Oct 2018 11:31:19 +0200 Subject: [PATCH 582/812] Remove all possible native php functions & use framework components --- .../Model/Product/Gallery/Processor.php | 33 ++++++++++++------- composer.json | 1 - 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index 225c502830695..048ad55985b72 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -57,25 +57,34 @@ class Processor */ protected $resourceModel; + /** + * @var \Magento\Framework\File\Mime + */ + protected $mime; + /** * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository * @param \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb * @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel + * @param \Magento\Framework\File\Mime $mime + * @throws \Magento\Framework\Exception\FileSystemException */ public function __construct( \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository, \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb, \Magento\Catalog\Model\Product\Media\Config $mediaConfig, \Magento\Framework\Filesystem $filesystem, - \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel + \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel, + \Magento\Framework\File\Mime $mime ) { $this->attributeRepository = $attributeRepository; $this->fileStorageDb = $fileStorageDb; $this->mediaConfig = $mediaConfig; $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->resourceModel = $resourceModel; + $this->mime = $mime; } /** @@ -186,10 +195,10 @@ public function addImage( $position = 0; $absoluteFilePath = $this->mediaDirectory->getAbsolutePath($file); - $imageMimeType = mime_content_type($absoluteFilePath); - $imageContent = file_get_contents($absoluteFilePath); + $imageMimeType = $this->mime->getMimeType($absoluteFilePath); + $imageContent = $this->mediaDirectory->readFile($absoluteFilePath); $imageBase64 = base64_encode($imageContent); - $imageName = pathinfo($destinationFile, PATHINFO_FILENAME); + $imageName = $pathinfo['filename']; if (!is_array($mediaGalleryData)) { $mediaGalleryData = ['images' => []]; @@ -203,17 +212,17 @@ public function addImage( $position++; $mediaGalleryData['images'][] = [ - 'file' => $fileName, - 'position' => $position, - 'label' => '', - 'disabled' => (int)$exclude, + 'file' => $fileName, + 'position' => $position, + 'label' => '', + 'disabled' => (int)$exclude, 'media_type' => 'image', - 'types' => $mediaAttribute, - 'content' => [ + 'types' => $mediaAttribute, + 'content' => [ 'data' => [ - ImageContentInterface::NAME => $imageName, + ImageContentInterface::NAME => $imageName, ImageContentInterface::BASE64_ENCODED_DATA => $imageBase64, - ImageContentInterface::TYPE => $imageMimeType, + ImageContentInterface::TYPE => $imageMimeType, ] ] ]; diff --git a/composer.json b/composer.json index 68bf1f1d8a8b0..e2a646275d98b 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,6 @@ "ext-xsl": "*", "ext-zip": "*", "lib-libxml": "*", - "ext-fileinfo": "*", "braintree/braintree_php": "3.35.0", "colinmollenhour/cache-backend-file": "~1.4.1", "colinmollenhour/cache-backend-redis": "1.10.5", From 88edd10e3cb93937e49fb04e30f4bd55ed3c7fd6 Mon Sep 17 00:00:00 2001 From: Timon de Groot <timon@marissen.net> Date: Wed, 31 Oct 2018 10:56:49 +0100 Subject: [PATCH 583/812] Fix numeric translation keys being dissolved by array_merge --- lib/internal/Magento/Framework/App/Language/Dictionary.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/Language/Dictionary.php b/lib/internal/Magento/Framework/App/Language/Dictionary.php index 294490a665cbe..d9a5ccb00d892 100644 --- a/lib/internal/Magento/Framework/App/Language/Dictionary.php +++ b/lib/internal/Magento/Framework/App/Language/Dictionary.php @@ -111,7 +111,9 @@ public function getDictionary($languageCode) /** @var Config $languageConfig */ $languageConfig = $packInfo['language']; $dictionary = $this->readPackCsv($languageConfig->getVendor(), $languageConfig->getPackage()); - $result = array_merge($result, $dictionary); + foreach ($dictionary as $key => $value) { + $result[$key] = $value; + } } return $result; } From 64606aaa1d5ee4b57605b8572f641dbf471aec0d Mon Sep 17 00:00:00 2001 From: Sergey Shvets <wert2all@gmail.com> Date: Wed, 31 Oct 2018 12:21:47 +0200 Subject: [PATCH 584/812] MAGETWO-95739: Zip code is not validated during checkout when "My billing and shipping address are the same" is unchecked --- .../Checkout/view/frontend/web/js/view/billing-address.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js index 6a2f329d095d6..6f9a1a46826da 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js @@ -73,9 +73,7 @@ function ( quote.paymentMethod.subscribe(function () { checkoutDataResolver.resolveBillingAddress(); }, this); - shippingRatesValidator.initFields( - 'checkout.steps.billing-step.payment.payments-list.checkmo-form.form-fields' - ); + shippingRatesValidator.initFields(this.get('name') + '.form-fields'); }, /** From 3bfe826e29ea0d1a16416aa8c6bc164c562fb643 Mon Sep 17 00:00:00 2001 From: Peter Samoilov <samoilov@aheadworks.com> Date: Wed, 31 Oct 2018 13:56:29 +0300 Subject: [PATCH 585/812] Added default value(y) for confirmation question --- setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php b/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php index 64b934061b6c1..69c369f1ec9f6 100644 --- a/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php +++ b/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php @@ -84,7 +84,8 @@ protected function execute(InputInterface $input, OutputInterface $output) if (($currentValue !== null) && ($inputOptions[$option->getName()] !== null)) { $dialog = $this->getHelperSet()->get('question'); $question = new Question( - '<question>Overwrite the existing configuration for ' . $option->getName() . '?[Y/n]</question>' + '<question>Overwrite the existing configuration for ' . $option->getName() . '?[Y/n]</question>', + 'y' ); if (strtolower($dialog->ask($input, $output, $question)) !== 'y') { $inputOptions[$option->getName()] = null; From bdce1b6d8bb67c00312e5d1c1693a0ca7b708a34 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Wed, 31 Oct 2018 13:23:05 +0200 Subject: [PATCH 586/812] ENGCOM-1928: Refactoring. --- app/code/Magento/Store/Block/Switcher.php | 20 ------ app/code/Magento/Store/ViewModel/Switcher.php | 72 +++++++++++++++++++ .../frontend/templates/switch/languages.phtml | 2 +- .../Theme/view/frontend/layout/default.xml | 7 +- 4 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 app/code/Magento/Store/ViewModel/Switcher.php diff --git a/app/code/Magento/Store/Block/Switcher.php b/app/code/Magento/Store/Block/Switcher.php index e162a2a0abe16..f15349f11066d 100644 --- a/app/code/Magento/Store/Block/Switcher.php +++ b/app/code/Magento/Store/Block/Switcher.php @@ -265,24 +265,4 @@ public function getTargetStorePostData(Store $store, $data = []) $data ); } - - /** - * Returns target store redirect url. - * - * @param Store $store - * @return string - */ - public function getTargetStoreRedirectUrl(Store $store) - { - return $this->getUrl( - 'stores/store/redirect', - [ - '___store' => $store->getCode(), - '___from_store' => $this->getCurrentStoreCode(), - ActionInterface::PARAM_NAME_URL_ENCODED => $this->urlHelper->getEncodedUrl( - $store->getCurrentUrl(false) - ), - ] - ); - } } diff --git a/app/code/Magento/Store/ViewModel/Switcher.php b/app/code/Magento/Store/ViewModel/Switcher.php new file mode 100644 index 0000000000000..b0d08f064073d --- /dev/null +++ b/app/code/Magento/Store/ViewModel/Switcher.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Store\ViewModel; + +use Magento\Framework\App\ActionInterface; +use Magento\Framework\Url\EncoderInterface; +use Magento\Framework\UrlInterface; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; + +/** + * Provides target store redirect url. + */ +class SwitcherUrlProvider implements \Magento\Framework\View\Element\Block\ArgumentInterface +{ + /** + * @var EncoderInterface + */ + private $encoder; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var UrlInterface + */ + private $urlBuilder; + + /** + * @param EncoderInterface $encoder + * @param StoreManagerInterface $storeManager + * @param UrlInterface $urlBuilder + */ + public function __construct( + EncoderInterface $encoder, + StoreManagerInterface $storeManager, + UrlInterface $urlBuilder + ) { + $this->encoder = $encoder; + $this->storeManager = $storeManager; + $this->urlBuilder = $urlBuilder; + } + + /** + * Returns target store redirect url. + * + * @param Store $store + * @return string + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function getTargetStoreRedirectUrl(Store $store): string + { + return $this->urlBuilder->getUrl( + 'stores/store/redirect', + [ + '___store' => $store->getCode(), + '___from_store' => $this->storeManager->getStore()->getCode(), + ActionInterface::PARAM_NAME_URL_ENCODED => $this->encoder->encode( + $store->getCurrentUrl(false) + ), + ] + ); + } +} diff --git a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml index 411a1ef3c9a32..a620c2ce71407 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml @@ -27,7 +27,7 @@ <?php foreach ($block->getStores() as $_lang): ?> <?php if ($_lang->getId() != $block->getCurrentStoreId()): ?> <li class="view-<?= $block->escapeHtml($_lang->getCode()) ?> switcher-option"> - <a href="<?= $block->escapeUrl($block->getTargetStoreRedirectUrl($_lang)) ?>"> + <a href="<?= $block->escapeUrl($block->getViewModel()->getTargetStoreRedirectUrl($_lang)) ?>"> <?= $block->escapeHtml($_lang->getName()) ?> </a> </li> diff --git a/app/code/Magento/Theme/view/frontend/layout/default.xml b/app/code/Magento/Theme/view/frontend/layout/default.xml index 716341f5a64a4..d6ec289edaa92 100644 --- a/app/code/Magento/Theme/view/frontend/layout/default.xml +++ b/app/code/Magento/Theme/view/frontend/layout/default.xml @@ -39,7 +39,11 @@ <argument name="label" translate="true" xsi:type="string">Skip to Content</argument> </arguments> </block> - <block class="Magento\Store\Block\Switcher" name="store_language" as="store_language" template="Magento_Store::switch/languages.phtml"/> + <block class="Magento\Store\Block\Switcher" name="store_language" as="store_language" template="Magento_Store::switch/languages.phtml"> + <arguments> + <argument name="view_model" xsi:type="object">Magento\Store\ViewModel\SwitcherUrlProvider</argument> + </arguments> + </block> <block class="Magento\Customer\Block\Account\Navigation" name="top.links"> <arguments> <argument name="css_class" xsi:type="string">header links</argument> @@ -82,6 +86,7 @@ <block class="Magento\Store\Block\Switcher" name="store.settings.language" template="Magento_Store::switch/languages.phtml"> <arguments> <argument name="id_modifier" xsi:type="string">nav</argument> + <argument name="view_model" xsi:type="object">Magento\Store\ViewModel\SwitcherUrlProvider</argument> </arguments> </block> <block class="Magento\Directory\Block\Currency" name="store.settings.currency" template="Magento_Directory::currency.phtml"> From 80da4ea87544caa583ab1c90ed251ea946a8be51 Mon Sep 17 00:00:00 2001 From: prakashpatel07 <prakash.patel@krishtechnolabs.com> Date: Wed, 31 Oct 2018 13:38:55 +0000 Subject: [PATCH 587/812] Fixed Last Logged-in date when customer authenticate via REST API. --- .../Integration/Model/CustomerTokenService.php | 13 ++++++++++++- .../Test/Unit/Model/CustomerTokenServiceTest.php | 8 +++++++- .../Magento/Integration/etc/webapi_rest/events.xml | 12 ++++++++++++ .../Magento/Integration/etc/webapi_soap/events.xml | 12 ++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Integration/etc/webapi_rest/events.xml create mode 100644 app/code/Magento/Integration/etc/webapi_soap/events.xml diff --git a/app/code/Magento/Integration/Model/CustomerTokenService.php b/app/code/Magento/Integration/Model/CustomerTokenService.php index 3c245804a9f6e..35d0424d3b4fa 100644 --- a/app/code/Magento/Integration/Model/CustomerTokenService.php +++ b/app/code/Magento/Integration/Model/CustomerTokenService.php @@ -14,6 +14,7 @@ use Magento\Integration\Model\ResourceModel\Oauth\Token\CollectionFactory as TokenCollectionFactory; use Magento\Integration\Model\Oauth\Token\RequestThrottler; use Magento\Framework\Exception\AuthenticationException; +use Magento\Framework\Event\ManagerInterface; class CustomerTokenService implements \Magento\Integration\Api\CustomerTokenServiceInterface { @@ -24,6 +25,11 @@ class CustomerTokenService implements \Magento\Integration\Api\CustomerTokenServ */ private $tokenModelFactory; + /** + * @var Magento\Framework\Event\ManagerInterface + */ + private $eventManager; + /** * Customer Account Service * @@ -55,17 +61,21 @@ class CustomerTokenService implements \Magento\Integration\Api\CustomerTokenServ * @param AccountManagementInterface $accountManagement * @param TokenCollectionFactory $tokenModelCollectionFactory * @param \Magento\Integration\Model\CredentialsValidator $validatorHelper + * @param \Magento\Framework\Event\ManagerInterface $eventManager */ public function __construct( TokenModelFactory $tokenModelFactory, AccountManagementInterface $accountManagement, TokenCollectionFactory $tokenModelCollectionFactory, - CredentialsValidator $validatorHelper + CredentialsValidator $validatorHelper, + ManagerInterface $eventManager = null ) { $this->tokenModelFactory = $tokenModelFactory; $this->accountManagement = $accountManagement; $this->tokenModelCollectionFactory = $tokenModelCollectionFactory; $this->validatorHelper = $validatorHelper; + $this->eventManager = $eventManager ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(ManagerInterface::class); } /** @@ -86,6 +96,7 @@ public function createCustomerAccessToken($username, $password) ) ); } + $this->eventManager->dispatch('customer_login', ['customer' => $customerDataObject]); $this->getRequestThrottler()->resetAuthenticationFailuresCount($username, RequestThrottler::USER_TYPE_CUSTOMER); return $this->tokenModelFactory->create()->createCustomerToken($customerDataObject->getId())->getToken(); } diff --git a/app/code/Magento/Integration/Test/Unit/Model/CustomerTokenServiceTest.php b/app/code/Magento/Integration/Test/Unit/Model/CustomerTokenServiceTest.php index 1a7c819343294..1bc7d4247080f 100644 --- a/app/code/Magento/Integration/Test/Unit/Model/CustomerTokenServiceTest.php +++ b/app/code/Magento/Integration/Test/Unit/Model/CustomerTokenServiceTest.php @@ -32,6 +32,9 @@ class CustomerTokenServiceTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Integration\Model\Oauth\Token|\PHPUnit_Framework_MockObject_MockObject */ private $_tokenMock; + /** @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $manager; + protected function setUp() { $this->_tokenFactoryMock = $this->getMockBuilder(\Magento\Integration\Model\Oauth\TokenFactory::class) @@ -67,11 +70,14 @@ protected function setUp() \Magento\Integration\Model\CredentialsValidator::class )->disableOriginalConstructor()->getMock(); + $this->manager = $this->createMock(\Magento\Framework\Event\ManagerInterface::class); + $this->_tokenService = new \Magento\Integration\Model\CustomerTokenService( $this->_tokenFactoryMock, $this->_accountManagementMock, $this->_tokenModelCollectionFactoryMock, - $this->validatorHelperMock + $this->validatorHelperMock, + $this->manager ); } diff --git a/app/code/Magento/Integration/etc/webapi_rest/events.xml b/app/code/Magento/Integration/etc/webapi_rest/events.xml new file mode 100644 index 0000000000000..e978698734277 --- /dev/null +++ b/app/code/Magento/Integration/etc/webapi_rest/events.xml @@ -0,0 +1,12 @@ +<?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:Event/etc/events.xsd"> + <event name="customer_login"> + <observer name="customer_log_login" instance="Magento\Customer\Observer\LogLastLoginAtObserver" /> + </event> +</config> diff --git a/app/code/Magento/Integration/etc/webapi_soap/events.xml b/app/code/Magento/Integration/etc/webapi_soap/events.xml new file mode 100644 index 0000000000000..e978698734277 --- /dev/null +++ b/app/code/Magento/Integration/etc/webapi_soap/events.xml @@ -0,0 +1,12 @@ +<?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:Event/etc/events.xsd"> + <event name="customer_login"> + <observer name="customer_log_login" instance="Magento\Customer\Observer\LogLastLoginAtObserver" /> + </event> +</config> From 02192264fb25a7bf4d61326650d03a7205b0c940 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 31 Oct 2018 16:45:01 +0300 Subject: [PATCH 588/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static test --- .../view/adminhtml/web/js/grouped-product-grid.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index c1a35cb0afede..f257cb2df729e 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -9,6 +9,7 @@ define([ 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid' ], function (_, registry, dynamicRowsGrid) { 'use strict'; + return dynamicRowsGrid.extend({ /** @@ -191,15 +192,6 @@ define([ return (~~this.currentPage() - 1) * this.pageSize + this.elems().pluck("name").indexOf(data.name); }, - /** - * Returns start index for current page - * - * @return {number} - */ - getStartIndex() { - return (~~this.currentPage() - 1) * this.pageSize; - }, - /** * Return Page Boundary * @@ -214,7 +206,7 @@ define([ * * @return {number} */ - getGlobalMaxPosition() { + getGlobalMaxPosition: function () { return _.max(this.recordData().map(function (r) { return ~~r.position })); From fff8dd3fae6aa65e19d7a5f539123b71d40c7078 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 31 Oct 2018 16:54:25 +0300 Subject: [PATCH 589/812] MAGETWO-91609: Problems with operator more/less in the "catalog Products List" widget - Fix static test --- .../Unit/Model/Condition/Sql/BuilderTest.php | 79 ++++--------------- 1 file changed, 17 insertions(+), 62 deletions(-) diff --git a/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php b/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php index 13bba8a6a28ab..9dcbbd18c4c20 100644 --- a/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php +++ b/app/code/Magento/Rule/Test/Unit/Model/Condition/Sql/BuilderTest.php @@ -91,30 +91,13 @@ public function testAttachConditionAsHtmlToCollection() ['getOperatorForValidate', 'getMappedSqlField', 'getAttribute', 'getBindArgumentValue'] ); - $abstractCondition->expects($this->once()) - ->method('getMappedSqlField') - ->will($this->returnValue('argument')); - - $abstractCondition->expects($this->once()) - ->method('getOperatorForValidate') - ->will($this->returnValue('>')); - - $abstractCondition->expects($this->at(1)) - ->method('getAttribute') - ->will($this->returnValue('attribute')); - - $abstractCondition->expects($this->at(2)) - ->method('getAttribute') - ->will($this->returnValue('attribute')); - - $abstractCondition->expects($this->once()) - ->method('getBindArgumentValue') - ->will($this->returnValue(10)); - - $conditions = [ - $abstractCondition - ]; + $abstractCondition->expects($this->once())->method('getMappedSqlField')->will($this->returnValue('argument')); + $abstractCondition->expects($this->once())->method('getOperatorForValidate')->will($this->returnValue('>')); + $abstractCondition->expects($this->at(1))->method('getAttribute')->will($this->returnValue('attribute')); + $abstractCondition->expects($this->at(2))->method('getAttribute')->will($this->returnValue('attribute')); + $abstractCondition->expects($this->once())->method('getBindArgumentValue')->will($this->returnValue(10)); + $conditions = [$abstractCondition]; $collection = $this->createPartialMock( \Magento\Eav\Model\Entity\Collection\AbstractCollection::class, [ @@ -122,7 +105,6 @@ public function testAttachConditionAsHtmlToCollection() 'getSelect' ] ); - $combine = $this->createPartialMock( \Magento\Rule\Model\Condition\Combine::class, [ @@ -131,10 +113,10 @@ public function testAttachConditionAsHtmlToCollection() 'getAggregator' ] ); + $resource = $this->createPartialMock(\Magento\Framework\DB\Adapter\Pdo\Mysql::class, ['getConnection']); $select = $this->createPartialMock(\Magento\Framework\DB\Select::class, ['where']); - $select->expects($this->never()) - ->method('where'); + $select->expects($this->never())->method('where'); $connection = $this->getMockForAbstractClass( \Magento\Framework\DB\Adapter\AdapterInterface::class, @@ -143,42 +125,15 @@ public function testAttachConditionAsHtmlToCollection() false ); - $connection->expects($this->once()) - ->method('quoteInto') - ->with(' > ?', 10) - ->will($this->returnValue(' > 10')); - - $collection->expects($this->once()) - ->method('getResource') - ->will($this->returnValue($resource)); - - $resource->expects($this->once()) - ->method('getConnection') - ->will($this->returnValue($connection)); - - $combine->expects($this->once()) - ->method('getValue') - ->willReturn('attribute'); - - $combine->expects($this->once()) - ->method('getAggregator') - ->willReturn(' AND '); - - $combine->expects($this->at(0)) - ->method('getConditions') - ->will($this->returnValue($conditions)); - - $combine->expects($this->at(1)) - ->method('getConditions') - ->will($this->returnValue($conditions)); - - $combine->expects($this->at(2)) - ->method('getConditions') - ->will($this->returnValue($conditions)); - - $combine->expects($this->at(3)) - ->method('getConditions') - ->will($this->returnValue($conditions)); + $connection->expects($this->once())->method('quoteInto')->with(' > ?', 10)->will($this->returnValue(' > 10')); + $collection->expects($this->once())->method('getResource')->will($this->returnValue($resource)); + $resource->expects($this->once())->method('getConnection')->will($this->returnValue($connection)); + $combine->expects($this->once())->method('getValue')->willReturn('attribute'); + $combine->expects($this->once())->method('getAggregator')->willReturn(' AND '); + $combine->expects($this->at(0))->method('getConditions')->will($this->returnValue($conditions)); + $combine->expects($this->at(1))->method('getConditions')->will($this->returnValue($conditions)); + $combine->expects($this->at(2))->method('getConditions')->will($this->returnValue($conditions)); + $combine->expects($this->at(3))->method('getConditions')->will($this->returnValue($conditions)); $this->_builder->attachConditionToCollection($collection, $combine); } From 9f568fb21b4c211c85fcf675fb504d2c1971be4d Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Wed, 31 Oct 2018 16:15:03 +0200 Subject: [PATCH 590/812] MAGETWO-96007: Customer address issue when creating or updating via API --- .../ResourceModel/CustomerRepository.php | 99 ++++++++++--------- 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php index 43ae2db0c2163..a053eee5cd09b 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php +++ b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php @@ -8,69 +8,80 @@ use Magento\Customer\Api\CustomerMetadataInterface; use Magento\Customer\Api\Data\CustomerInterface; -use Magento\Customer\Model\Delegation\Data\NewOperation; +use Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory; +use Magento\Framework\Api\ExtensibleDataObjectConverter; +use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; +use Magento\Customer\Model\CustomerFactory; +use Magento\Customer\Model\CustomerRegistry; +use Magento\Customer\Model\Data\CustomerSecureFactory; use Magento\Customer\Model\Customer\NotificationStorage; +use Magento\Customer\Model\Delegation\Data\NewOperation; +use Magento\Customer\Api\CustomerRepositoryInterface; use Magento\Framework\Api\DataObjectHelper; use Magento\Framework\Api\ImageProcessorInterface; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Event\ManagerInterface; use Magento\Customer\Model\Delegation\Storage as DelegatedStorage; use Magento\Framework\App\ObjectManager; +use Magento\Store\Model\StoreManagerInterface; /** * Customer repository. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) */ -class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInterface +class CustomerRepository implements CustomerRepositoryInterface { /** - * @var \Magento\Customer\Model\CustomerFactory + * @var CustomerFactory */ protected $customerFactory; /** - * @var \Magento\Customer\Model\Data\CustomerSecureFactory + * @var CustomerSecureFactory */ protected $customerSecureFactory; /** - * @var \Magento\Customer\Model\CustomerRegistry + * @var CustomerRegistry */ protected $customerRegistry; /** - * @var \Magento\Customer\Model\ResourceModel\AddressRepository + * @var AddressRepository */ protected $addressRepository; /** - * @var \Magento\Customer\Model\ResourceModel\Customer + * @var Customer */ protected $customerResourceModel; /** - * @var \Magento\Customer\Api\CustomerMetadataInterface + * @var CustomerMetadataInterface */ protected $customerMetadata; /** - * @var \Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory + * @var CustomerSearchResultsInterfaceFactory */ protected $searchResultsFactory; /** - * @var \Magento\Framework\Event\ManagerInterface + * @var ManagerInterface */ protected $eventManager; /** - * @var \Magento\Store\Model\StoreManagerInterface + * @var StoreManagerInterface */ protected $storeManager; /** - * @var \Magento\Framework\Api\ExtensibleDataObjectConverter + * @var ExtensibleDataObjectConverter */ protected $extensibleDataObjectConverter; @@ -85,7 +96,7 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte protected $imageProcessor; /** - * @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface + * @var JoinProcessorInterface */ protected $extensionAttributesJoinProcessor; @@ -105,38 +116,38 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte private $delegatedStorage; /** - * @param \Magento\Customer\Model\CustomerFactory $customerFactory - * @param \Magento\Customer\Model\Data\CustomerSecureFactory $customerSecureFactory - * @param \Magento\Customer\Model\CustomerRegistry $customerRegistry - * @param \Magento\Customer\Model\ResourceModel\AddressRepository $addressRepository - * @param \Magento\Customer\Model\ResourceModel\Customer $customerResourceModel - * @param \Magento\Customer\Api\CustomerMetadataInterface $customerMetadata - * @param \Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory $searchResultsFactory - * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter + * @param CustomerFactory $customerFactory + * @param CustomerSecureFactory $customerSecureFactory + * @param CustomerRegistry $customerRegistry + * @param AddressRepository $addressRepository + * @param Customer $customerResourceModel + * @param CustomerMetadataInterface $customerMetadata + * @param CustomerSearchResultsInterfaceFactory $searchResultsFactory + * @param ManagerInterface $eventManager + * @param StoreManagerInterface $storeManager + * @param ExtensibleDataObjectConverter $extensibleDataObjectConverter * @param DataObjectHelper $dataObjectHelper * @param ImageProcessorInterface $imageProcessor - * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + * @param JoinProcessorInterface $extensionAttributesJoinProcessor * @param CollectionProcessorInterface $collectionProcessor * @param NotificationStorage $notificationStorage * @param DelegatedStorage|null $delegatedStorage * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( - \Magento\Customer\Model\CustomerFactory $customerFactory, - \Magento\Customer\Model\Data\CustomerSecureFactory $customerSecureFactory, - \Magento\Customer\Model\CustomerRegistry $customerRegistry, - \Magento\Customer\Model\ResourceModel\AddressRepository $addressRepository, - \Magento\Customer\Model\ResourceModel\Customer $customerResourceModel, - \Magento\Customer\Api\CustomerMetadataInterface $customerMetadata, - \Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory $searchResultsFactory, - \Magento\Framework\Event\ManagerInterface $eventManager, - \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter, + CustomerFactory $customerFactory, + CustomerSecureFactory $customerSecureFactory, + CustomerRegistry $customerRegistry, + AddressRepository $addressRepository, + Customer $customerResourceModel, + CustomerMetadataInterface $customerMetadata, + CustomerSearchResultsInterfaceFactory $searchResultsFactory, + ManagerInterface $eventManager, + StoreManagerInterface $storeManager, + ExtensibleDataObjectConverter $extensibleDataObjectConverter, DataObjectHelper $dataObjectHelper, ImageProcessorInterface $imageProcessor, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, + JoinProcessorInterface $extensionAttributesJoinProcessor, CollectionProcessorInterface $collectionProcessor, NotificationStorage $notificationStorage, DelegatedStorage $delegatedStorage = null @@ -156,8 +167,7 @@ public function __construct( $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; $this->collectionProcessor = $collectionProcessor; $this->notificationStorage = $notificationStorage; - $this->delegatedStorage = $delegatedStorage - ?? ObjectManager::getInstance()->get(DelegatedStorage::class); + $this->delegatedStorage = $delegatedStorage ?? ObjectManager::getInstance()->get(DelegatedStorage::class); } /** @@ -200,13 +210,13 @@ public function save(CustomerInterface $customer, $passwordHash = null) $customerModel->setRpToken(null); $customerModel->setRpTokenCreatedAt(null); } - if (!array_key_exists('default_billing', $customerArr) + if (!array_key_exists('addresses', $customerArr) && null !== $prevCustomerDataArr && array_key_exists('default_billing', $prevCustomerDataArr) ) { $customerModel->setDefaultBilling($prevCustomerDataArr['default_billing']); } - if (!array_key_exists('default_shipping', $customerArr) + if (!array_key_exists('addresses', $customerArr) && null !== $prevCustomerDataArr && array_key_exists('default_shipping', $prevCustomerDataArr) ) { @@ -371,15 +381,12 @@ public function deleteById($customerId) * Helper function that adds a FilterGroup to the collection. * * @deprecated 100.2.0 - * @param \Magento\Framework\Api\Search\FilterGroup $filterGroup - * @param \Magento\Customer\Model\ResourceModel\Customer\Collection $collection + * @param FilterGroup $filterGroup + * @param Collection $collection * @return void - * @throws \Magento\Framework\Exception\InputException */ - protected function addFilterGroupToCollection( - \Magento\Framework\Api\Search\FilterGroup $filterGroup, - \Magento\Customer\Model\ResourceModel\Customer\Collection $collection - ) { + protected function addFilterGroupToCollection(FilterGroup $filterGroup, Collection $collection) + { $fields = []; foreach ($filterGroup->getFilters() as $filter) { $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; From 24b690fbc3610641c674f88893fd01b0aab70118 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 31 Oct 2018 17:19:46 +0300 Subject: [PATCH 591/812] MAGETWO-91649: Magento ignore store-level url_key of child category in URL rewrite process for global scope - Fix static test --- .../Observer/CategoryUrlPathAutogeneratorObserver.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php index 5c7a8b16a666e..d692918aff6a6 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php @@ -14,6 +14,9 @@ use Magento\Framework\Event\ObserverInterface; use Magento\Store\Model\Store; +/** + * Class for set or update url path. + */ class CategoryUrlPathAutogeneratorObserver implements ObserverInterface { /** @@ -55,6 +58,8 @@ public function __construct( } /** + * Method for update/set url path. + * * @param \Magento\Framework\Event\Observer $observer * @return void * @throws \Magento\Framework\Exception\LocalizedException @@ -81,6 +86,8 @@ public function execute(\Magento\Framework\Event\Observer $observer) } /** + * Update url path for children category. + * * @param Category $category * @return void */ @@ -121,6 +128,8 @@ protected function isGlobalScope($storeId) } /** + * Update url path for category. + * * @param Category $category * @return void */ From 7daec41bcf5451b2ca7cb11b3e4784a9049f090c Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Wed, 31 Oct 2018 09:39:34 -0500 Subject: [PATCH 592/812] MAGETWO-94313: Random test failures on jenkins - unskip Magento\Reports\Test\TestCase\ProductsInCartReportEntityTest --- .../Reports/Test/TestCase/ProductsInCartReportEntityTest.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.xml index fd0d169967161..e13d31342dba1 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.xml @@ -8,14 +8,12 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Reports\Test\TestCase\ProductsInCartReportEntityTest" summary="Products In Cart Report" ticketId="MAGETWO-27952"> <variation name="ProductsInCartReportEntityVariation1"> - <data name="issue" xsi:type="string">MQE-1160</data> <data name="product/dataset" xsi:type="string">default</data> <data name="carts" xsi:type="string">1</data> <data name="isGuest" xsi:type="string">0</data> <constraint name="Magento\Reports\Test\Constraint\AssertProductInCartResult" /> </variation> <variation name="ProductsInCartReportEntityVariation2"> - <data name="issue" xsi:type="string">MQE-1160</data> <data name="product/dataset" xsi:type="string">default</data> <data name="carts" xsi:type="string">2</data> <data name="isGuest" xsi:type="string">1</data> From 07c2d7a3447e6c8079e02e331777e00ba835e6ed Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Wed, 31 Oct 2018 16:53:51 +0200 Subject: [PATCH 593/812] MAGETWO-96026: Create MFTF test for MAGETWO-93973 --- .../Test/Mftf/Page/AdminProductCreatePage.xml | 1 + ...minProductFormAdvancedInventorySection.xml | 37 +++++++++ .../Mftf/Section/AdminProductFormSection.xml | 1 + ...IncrementsWorkWithDecimalinventoryTest.xml | 75 +++++++++++++++++++ .../Section/StorefrontQuickSearchSection.xml | 2 +- 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductCreatePage.xml b/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductCreatePage.xml index fc776b49ba213..b3ed3f478f810 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductCreatePage.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductCreatePage.xml @@ -17,5 +17,6 @@ <section name="AdminProductMessagesSection"/> <section name="AdminProductFormRelatedUpSellCrossSellSection"/> <section name="AdminProductFormAdvancedPricingSection"/> + <section name="AdminProductFormAdvancedInventorySection"/> </page> </pages> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml new file mode 100644 index 0000000000000..e1272899b78ab --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml @@ -0,0 +1,37 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminProductFormAdvancedInventorySection"> + <!--<element name="customerGroupPriceAddButton" type="button" selector="[data-action='add_new_row']" timeout="30"/>--> + <!--<element name="customerGroupPriceDeleteButton" type="button" selector="[data-action='remove_row']" timeout="30"/>--> + <!--<element name="advancedPricingCloseButton" type="button" selector=".product_form_product_form_advanced_pricing_modal button.action-close" timeout="30"/>--> + <!--<element name="productTierPriceWebsiteSelect" type="select" selector="[name='product[tier_price][{{var1}}][website_id]']" parameterized="true"/>--> + <!--<element name="productTierPriceCustGroupSelect" type="select" selector="[name='product[tier_price][{{var1}}][cust_group]']" parameterized="true"/>--> + <!--<element name="productTierPriceQtyInput" type="input" selector="[name='product[tier_price][{{var1}}][price_qty]']" parameterized="true"/>--> + <!--<element name="productTierPriceValueTypeSelect" type="select" selector="[name='product[tier_price][{{var1}}][value_type]']" parameterized="true"/>--> + <!--<element name="productTierPriceFixedPriceInput" type="input" selector="[name='product[tier_price][{{var1}}][price]']" parameterized="true"/>--> + <!--<element name="productTierPricePercentageValuePriceInput" type="input" selector="[name='product[tier_price][{{var1}}][percentage_value]']" parameterized="true"/>--> + <!--<element name="specialPrice" type="input" selector="input[name='product[special_price]']"/>--> + + <element name="enableQtyIncrements" type="select" selector="//*[@name='product[stock_data][enable_qty_increments]']"/> + <element name="enableQtyIncrementsOptions" type="select" selector="//*[@name='product[stock_data][enable_qty_increments]']//option[contains(@value, '{{var1}}')]" parameterized="true"/> + <element name="enableQtyIncrementsUseConfigSettings" type="checkbox" selector="//input[@name='product[stock_data][use_config_enable_qty_inc]']"/> + <element name="qtyUsesDecimals" type="select" selector="//*[@name='product[stock_data][is_qty_decimal]']"/> + <element name="qtyUsesDecimalsOptions" type="select" selector="//*[@name='product[stock_data][is_qty_decimal]']//option[contains(@value, '{{var1}}')]" parameterized="true"/> + <element name="qtyIncrements" type="input" selector="//input[@name='product[stock_data][qty_increments]']"/> + <element name="qtyIncrementsUseConfigSettings" type="checkbox" selector="//input[@name='product[stock_data][use_config_qty_increments]']"/> + + <element name="doneButton" type="button" selector="//aside[contains(@class,'product_form_product_form_advanced_inventory_modal')]//button[contains(@data-role,'action')]" timeout="5"/> + </section> +</sections> + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml index 03df9d2a88107..9ec0dbf9f262c 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml @@ -28,6 +28,7 @@ <element name="advancedPricingLink" type="button" selector="button[data-index='advanced_pricing_button']"/> <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="advancedInventoryLink" type="input" selector="//button[contains(@data-index, 'advanced_inventory_button')]"/> <element name="productStockStatus" type="select" selector="select[name='product[quantity_and_stock_status][is_in_stock]']"/> <element name="productWeight" type="input" selector=".admin__field[data-index=weight] input"/> <element name="productWeightSelect" type="select" selector="select[name='product[product_has_weight]']"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml new file mode 100644 index 0000000000000..7a774c585c9cd --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml @@ -0,0 +1,75 @@ +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest"> + <annotations> + <features value="Tiered pricing and quantity increments work with decimal inventory"/> + <stories value="Tiered pricing and quantity increments work with decimal inventory"/> + <title value="Tiered pricing and quantity increments work with decimal inventory"/> + <description value="Tiered pricing and quantity increments work with decimal inventory"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-91178"/> + <group value="product"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + <createData entity="SimpleProduct" stepKey="createPreReqSimpleProduct"> + <requiredEntity createDataKey="createPreReqCategory"/> + </createData> + </before> + <after> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> + <deleteData createDataKey="createPreReqSimpleProduct" stepKey="deletePreReqSimpleProduct"/> + </after> + <!--Step1. Login as admin. Go to Catalog > Products page. Filtering *prod1*. Open *prod1* to edit--> + <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin" /> + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="filterGroupedProductOptions"> + <argument name="product" value="SimpleProduct"/> + </actionGroup> + <click selector="{{AdminProductGridSection.productGridNameProduct('$$createPreReqSimpleProduct.name$$')}}" + stepKey="clickOpenProductForEdit"/> + <waitForPageLoad time="30" stepKey="waitForProductEditOpen"/> + <!--Step2. Open *Advanced Inventory* pop-up (Click on *Advanced Inventory* link). Set *Qty Uses Decimals* to *Yes*. Click on button *Done* --> + <click selector="{{AdminProductFormSection.advancedInventoryLink}}" stepKey="clickOnAdvancedInventoryLink"/> + <scrollTo selector="{{AdminProductFormAdvancedInventorySection.qtyUsesDecimals}}" stepKey="scrollToQtyUsesDecimalsDropBox"/> + <click selector="{{AdminProductFormAdvancedInventorySection.qtyUsesDecimals}}" stepKey="clickOnQtyUsesDecimalsDropBox"/> + <click selector="{{AdminProductFormAdvancedInventorySection.qtyUsesDecimalsOptions('1')}}" stepKey="chooseYesOnQtyUsesDecimalsDropBox"/> + <click selector="{{AdminProductFormAdvancedInventorySection.doneButton}}" stepKey="clickOnDoneButton"/> + <!--Step3. Open *Advanced Pricing* pop-up (Click on *Advanced Pricing* link). Click on *Add* button. Fill *0.5* in *Quantity*--> + <scrollTo selector="{{AdminProductFormSection.productName}}" stepKey="scrollToProductName"/> + <click selector="{{AdminProductFormSection.advancedPricingLink}}" stepKey="clickOnAdvancedPricingLink1"/> + <click selector="{{AdminProductFormAdvancedPricingSection.customerGroupPriceAddButton}}" stepKey="clickOnCustomerGroupPriceAddButton"/> + <fillField selector="{{AdminProductFormAdvancedPricingSection.productTierPriceQtyInput('0')}}" userInput="0.5" stepKey="fillProductTierPriceQty"/> + <!--Step4. Close *Advanced Pricing* (Click on button *Done*). Save *prod1* (Click on button *Save*)--> + <click selector="{{AdminProductFormAdvancedPricingSection.doneButton}}" stepKey="clickOnDoneButton2"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickOnSaveButton"/> + + <!--The code should be uncommented after fix MAGETWO-96016--> + <!--<click selector="{{AdminProductFormSection.advancedPricingLink}}" stepKey="clickOnAdvancedPricingLink2"/>--> + <!--<seeInField userInput="0.5" selector="{{AdminProductFormAdvancedPricingSection.productTierPriceQtyInput('0')}}" stepKey="seeInField1"/>--> + <!--<click selector="{{AdminProductFormAdvancedPricingSection.advancedPricingCloseButton}}" stepKey="clickOnCloseButton"/>--> + + <!--Step5. Open *Advanced Inventory* pop-up. Set *Enable Qty Increments* to *Yes*. Fill *.5* in *Qty Increments*--> + <click selector="{{AdminProductFormSection.advancedInventoryLink}}" stepKey="clickOnAdvancedInventoryLink2"/> + <scrollTo selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrements}}" stepKey="scrollToEnableQtyIncrements"/> + <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrementsUseConfigSettings}}" stepKey="clickOnEnableQtyIncrementsUseConfigSettingsCheckbox"/> + <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrements}}" stepKey="clickOnEnableQtyIncrements"/> + <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrementsOptions(('1'))}}" stepKey="chooseYesOnEnableQtyIncrements"/> + <click selector="{{AdminProductFormAdvancedInventorySection.qtyIncrementsUseConfigSettings}}" stepKey="clickOnQtyIncrementsUseConfigSettings"/> + <fillField selector="{{AdminProductFormAdvancedInventorySection.qtyIncrements}}" userInput=".5" stepKey="fillQtyIncrements"/> + <!--Step6. Close *Advanced Inventory* (Click on button *Done*). Save *prod1* (Click on button *Save*) --> + <click selector="{{AdminProductFormAdvancedInventorySection.doneButton}}" stepKey="clickOnDoneButton3"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickOnSaveButton2"/> + <!--Step7. Open *Customer view* (Go to *Store Front*). Open *prod1* page (Find via search and click on product name) --> + <amOnPage url="{{StorefrontHomePage.url}}$$createPreReqSimpleProduct.custom_attributes[url_key]$$.html" stepKey="amOnProductPage"/> + <!--Step8. Fill *1.5* in *Qty*. Click on button *Add to Cart*--> + <fillField selector="{{StorefrontProductPageSection.qtyInput}}" userInput="1.5" stepKey="fillQty"/> + <click selector="{{StorefrontProductPageSection.addToCartBtn}}" stepKey="clickOnAddToCart"/> + <waitForElementVisible selector="{{StorefrontProductPageSection.successMsg}}" time="30" stepKey="waitForProductAdded"/> + <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createPreReqSimpleProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> + <!--Step9. Click on *Cart* icon. Click on *View and Edit Cart* link. Change *Qty* value to *5.5*--> + <actionGroup ref="clickViewAndEditCartFromMiniCart" stepKey="goToShoppingCartFromMinicart"/> + <fillField selector="{{CheckoutCartProductSection.ProductQuantityByName(('$$createPreReqSimpleProduct.name$$'))}}" userInput="5.5" stepKey="fillQty2"/> + <click selector="{{CheckoutCartProductSection.updateShoppingCartButton}}" stepKey="clickOnUpdateShoppingCartButton"/> + <seeInField userInput="5.5" selector="{{CheckoutCartProductSection.ProductQuantityByName(('$$createPreReqSimpleProduct.name$$'))}}" stepKey="seeInField2"/> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml b/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml index 2b08e9b4b85ec..6baa3ff54fca0 100644 --- a/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml +++ b/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml @@ -8,7 +8,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="StorefrontQuickSearchSection"> + <section name="StorefrontQuickSearchSection">/ <element name="searchPhrase" type="input" selector="#search"/> <element name="searchButton" type="button" selector="button.action.search" timeout="30"/> </section> From 3e94424757aa1b8ad2febc89617f5b199057b8ec Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Wed, 31 Oct 2018 17:12:26 +0200 Subject: [PATCH 594/812] MAGETWO-96026: Create MFTF test for MAGETWO-93973 --- .../AdminProductFormAdvancedInventorySection.xml | 12 ------------ .../Mftf/Section/StorefrontQuickSearchSection.xml | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml index e1272899b78ab..0314534dcddfb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml @@ -9,17 +9,6 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminProductFormAdvancedInventorySection"> - <!--<element name="customerGroupPriceAddButton" type="button" selector="[data-action='add_new_row']" timeout="30"/>--> - <!--<element name="customerGroupPriceDeleteButton" type="button" selector="[data-action='remove_row']" timeout="30"/>--> - <!--<element name="advancedPricingCloseButton" type="button" selector=".product_form_product_form_advanced_pricing_modal button.action-close" timeout="30"/>--> - <!--<element name="productTierPriceWebsiteSelect" type="select" selector="[name='product[tier_price][{{var1}}][website_id]']" parameterized="true"/>--> - <!--<element name="productTierPriceCustGroupSelect" type="select" selector="[name='product[tier_price][{{var1}}][cust_group]']" parameterized="true"/>--> - <!--<element name="productTierPriceQtyInput" type="input" selector="[name='product[tier_price][{{var1}}][price_qty]']" parameterized="true"/>--> - <!--<element name="productTierPriceValueTypeSelect" type="select" selector="[name='product[tier_price][{{var1}}][value_type]']" parameterized="true"/>--> - <!--<element name="productTierPriceFixedPriceInput" type="input" selector="[name='product[tier_price][{{var1}}][price]']" parameterized="true"/>--> - <!--<element name="productTierPricePercentageValuePriceInput" type="input" selector="[name='product[tier_price][{{var1}}][percentage_value]']" parameterized="true"/>--> - <!--<element name="specialPrice" type="input" selector="input[name='product[special_price]']"/>--> - <element name="enableQtyIncrements" type="select" selector="//*[@name='product[stock_data][enable_qty_increments]']"/> <element name="enableQtyIncrementsOptions" type="select" selector="//*[@name='product[stock_data][enable_qty_increments]']//option[contains(@value, '{{var1}}')]" parameterized="true"/> <element name="enableQtyIncrementsUseConfigSettings" type="checkbox" selector="//input[@name='product[stock_data][use_config_enable_qty_inc]']"/> @@ -27,7 +16,6 @@ <element name="qtyUsesDecimalsOptions" type="select" selector="//*[@name='product[stock_data][is_qty_decimal]']//option[contains(@value, '{{var1}}')]" parameterized="true"/> <element name="qtyIncrements" type="input" selector="//input[@name='product[stock_data][qty_increments]']"/> <element name="qtyIncrementsUseConfigSettings" type="checkbox" selector="//input[@name='product[stock_data][use_config_qty_increments]']"/> - <element name="doneButton" type="button" selector="//aside[contains(@class,'product_form_product_form_advanced_inventory_modal')]//button[contains(@data-role,'action')]" timeout="5"/> </section> </sections> diff --git a/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml b/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml index 6baa3ff54fca0..2b08e9b4b85ec 100644 --- a/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml +++ b/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchSection.xml @@ -8,7 +8,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="StorefrontQuickSearchSection">/ + <section name="StorefrontQuickSearchSection"> <element name="searchPhrase" type="input" selector="#search"/> <element name="searchButton" type="button" selector="button.action.search" timeout="30"/> </section> From d70ff4be68f9e084cc4e11de4092a6775e452b92 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 31 Oct 2018 10:38:14 -0500 Subject: [PATCH 595/812] MAGETWO-95773: Credit memo is created instead of returning error via invoice refund API for Bundle product - fix unit and static tests --- .../Validation/CreationQuantityValidator.php | 5 +++++ .../Sales/Model/Order/ItemRepository.php | 4 ++-- .../Unit/Model/Order/ItemRepositoryTest.php | 22 +++++++++++++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php index fdc5e2658b9ed..93a4e701e0322 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Item/Validation/CreationQuantityValidator.php @@ -30,6 +30,7 @@ class CreationQuantityValidator implements ValidatorInterface /** * ItemCreationQuantityValidator constructor. + * * @param OrderItemRepositoryInterface $orderItemRepository * @param mixed $context */ @@ -65,6 +66,8 @@ public function validate($entity) } /** + * Check the quantity to refund is greater than the unrefunded quantity + * * @param Item $orderItem * @param int $qty * @return bool @@ -75,6 +78,8 @@ private function isQtyAvailable(Item $orderItem, $qty) } /** + * Check to see if Item is part of the order + * * @param OrderItemInterface $orderItem * @return bool */ diff --git a/app/code/Magento/Sales/Model/Order/ItemRepository.php b/app/code/Magento/Sales/Model/Order/ItemRepository.php index 2ea9831336cc2..b1ff747d4f487 100644 --- a/app/code/Magento/Sales/Model/Order/ItemRepository.php +++ b/app/code/Magento/Sales/Model/Order/ItemRepository.php @@ -95,7 +95,7 @@ public function __construct( } /** - * load entity + * Load entity * * @param int $id * @return OrderItemInterface @@ -230,7 +230,7 @@ private function addParentItem(OrderItemInterface $orderItem) $orderItem->setParentItem($this->get($parentId)); } else { foreach ($orderItem->getOrder()->getAllItems() as $item) { - if($item->getParentItemId() === $orderItem->getItemId()) { + if ($item->getParentItemId() === $orderItem->getItemId()) { $item->setParentItem($orderItem); } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php index 8be2c3c8612d7..c19b4cbc3cb50 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php @@ -156,18 +156,27 @@ public function testGet() $productOption = $this->getProductOptionMock(); $orderItemMock = $this->getOrderMock($productType, $productOption); + $orderMock = $this->createMock(\Magento\Sales\Model\Order::class); + $orderMock->expects($this->once()) + ->method('getAllItems') + ->willReturn([$orderItemMock]); + $orderItemMock->expects($this->once()) ->method('load') ->with($orderItemId) ->willReturn($orderItemMock); - $orderItemMock->expects($this->once()) + $orderItemMock->expects($this->exactly(2)) ->method('getItemId') ->willReturn($orderItemId); + $orderItemMock->expects($this->once()) + ->method('getOrder') + ->willReturn($orderMock); $this->metadata->expects($this->once()) ->method('getNewInstance') ->willReturn($orderItemMock); + $model = $this->getModel($orderItemMock, $productType); $this->assertSame($orderItemMock, $model->get($orderItemId)); @@ -213,11 +222,17 @@ public function testDeleteById() $orderItemMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class) ->disableOriginalConstructor() ->getMock(); + + $orderMock = $this->createMock(\Magento\Sales\Model\Order::class); + $orderMock->expects($this->once()) + ->method('getAllItems') + ->willReturn([$orderItemMock]); + $orderItemMock->expects($this->once()) ->method('load') ->with($orderItemId) ->willReturn($orderItemMock); - $orderItemMock->expects($this->once()) + $orderItemMock->expects($this->exactly(2)) ->method('getItemId') ->willReturn($orderItemId); $orderItemMock->expects($this->once()) @@ -226,6 +241,9 @@ public function testDeleteById() $orderItemMock->expects($this->once()) ->method('getBuyRequest') ->willReturn($requestMock); + $orderItemMock->expects($this->once()) + ->method('getOrder') + ->willReturn($orderMock); $orderItemResourceMock = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class) ->disableOriginalConstructor() From 413a03686976ccf06c240783ddfdd2632af6d7cc Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 31 Oct 2018 13:15:39 -0500 Subject: [PATCH 596/812] MAGETWO-95773: Credit memo is created instead of returning error via invoice refund API for Bundle product - remove empty line --- .../Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php index c19b4cbc3cb50..5e1b49c0013e3 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php @@ -176,7 +176,6 @@ public function testGet() ->method('getNewInstance') ->willReturn($orderItemMock); - $model = $this->getModel($orderItemMock, $productType); $this->assertSame($orderItemMock, $model->get($orderItemId)); From 9cd11c65105f64cdcbced489739221b7bc6312f9 Mon Sep 17 00:00:00 2001 From: Tom Reece <treece@adobe.com> Date: Wed, 31 Oct 2018 13:37:42 -0500 Subject: [PATCH 597/812] MQE-1304: MFTF test failures between 5pm PDT and midnight PDT - Attempt to fix other test failures that happened during the PR --- .../Test/Mftf/Test/AdminResetCustomerPasswordTest.xml | 6 ++++-- .../ChangeStatusProductUsingProductGridActionGroup.xml | 7 +++---- .../Quote/Test/Mftf/Section/AdminProductGridSection.xml | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml index 0ca1d72a3ae1d..fb67838e941b6 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminResetCustomerPasswordTest.xml @@ -10,8 +10,8 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="AdminResetCustomerPasswordTest"> <annotations> - <features value="Customer"/> - <stories value="Admin should be able to reset an existing customer's password"/> + <stories value="Reset password"/> + <title value="Admin should be able to reset customer password"/> <description value="Admin should be able to reset customer password"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-30875"/> @@ -25,6 +25,8 @@ <deleteData createDataKey="customer" stepKey="deleteCustomer"/> <actionGroup ref="logout" stepKey="logout"/> </after> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> <!--Edit customer info--> <actionGroup ref="OpenEditCustomerFromAdminActionGroup" stepKey="OpenEditCustomerFrom"> <argument name="customer" value="$$customer$$"/> diff --git a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml index dba4a94f3db2a..9698f9cef4219 100644 --- a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml +++ b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml @@ -6,8 +6,7 @@ */ --> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <!--Disabled a product by filtering grid and using change status action--> <actionGroup name="ChangeStatusProductUsingProductGridActionGroup"> <arguments> @@ -23,10 +22,10 @@ <see selector="{{AdminProductGridSection.productGridCell('1', 'SKU')}}" userInput="{{product.sku}}" stepKey="seeProductSkuInGrid"/> <click selector="{{AdminProductGridSection.multicheckDropdown}}" stepKey="openMulticheckDropdown"/> <click selector="{{AdminProductGridSection.multicheckOption('Select All')}}" stepKey="selectAllProductInFilteredGrid"/> - <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickActionDropdown"/> <click selector="{{AdminProductGridSection.bulkActionOption('Change status')}}" stepKey="clickChangeStatusAction"/> - <click selector="{{AdminProductGridSection.changeStatus('status')}}" stepKey="clickChangeStatusDisabled" parameterized="true"/> + <click selector="{{AdminProductGridSection.changeStatus('status')}}" stepKey="clickChangeStatusDisabled"/> + <waitForPageLoad stepKey="waitForDisable"/> <see selector="{{AdminMessagesSection.success}}" userInput="A total of 1 record(s) have been updated." stepKey="seeSuccessMessage"/> <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial2"/> </actionGroup> diff --git a/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml b/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml index 32ac73aca7c03..0ca252aa73545 100644 --- a/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml +++ b/app/code/Magento/Quote/Test/Mftf/Section/AdminProductGridSection.xml @@ -7,8 +7,8 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminProductGridSection"> - <element name="changeStatus" selector="//div[contains(@class,'admin__data-grid-header-row') and contains(@class, 'row')]//div[contains(@class, 'action-menu-item')]//ul/li/span[text() = '{{status}}']" stepKey="clickChangeStatus" parameterized="true"/> + <element name="changeStatus" type="button" selector="//div[contains(@class,'admin__data-grid-header-row') and contains(@class, 'row')]//div[contains(@class, 'action-menu-item')]//ul/li/span[text() = '{{status}}']" parameterized="true"/> </section> </sections> From 5d84640f097dd94a361a6b0b1085e13da472a360 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Wed, 31 Oct 2018 20:17:21 -0500 Subject: [PATCH 598/812] MAGETWO-95659: Fix and Unskip MTF OnePageCheckoutOfflinePaymentMethodsTest --- .../OnePageCheckoutOfflinePaymentMethodsTest.xml | 11 ++++------- .../Test/TestStep/SelectCheckoutMethodStep.php | 11 +++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml index 7c12b546d1359..361c5031f3317 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml @@ -22,7 +22,6 @@ <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> </variation> <variation name="OnePageCheckoutUsingRegisterLink" summary="Customer is redirected to checkout on login if guest is disabled, flow with registration new Customer" ticketId="MAGETWO-49917"> - <data name="issue" xsi:type="string">MAGETWO-59816: Redirect works improperly in a browser incognito mode</data> <data name="tag" xsi:type="string">severity:S1</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="customer/dataset" xsi:type="string">register_customer</data> @@ -57,7 +56,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="OnePageCheckoutTestVariation2" summary="US customer during checkout using coupon for all customer groups"> - <data name="tag" xsi:type="string">stable:no, severity:S0</data> + <data name="tag" xsi:type="string">severity:S0</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups</data> <data name="customer/dataset" xsi:type="string">default</data> @@ -79,7 +78,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="OnePageCheckoutTestVariation3" summary="Checkout as UK guest with simple product" ticketId="MAGETWO-42603, MAGETWO-43282, MAGETWO-43318"> - <data name="tag" xsi:type="string">severity:S1, stable:no</data> + <data name="tag" xsi:type="string">severity:S1</data> <data name="products/0" xsi:type="string">catalogProductSimple::product_with_qty_25</data> <data name="expectedQty/0" xsi:type="string">0</data> <data name="expectedStockStatus/0" xsi:type="string">out of stock</data> @@ -92,7 +91,7 @@ <item name="grandTotal" xsi:type="string">375.00</item> </data> <data name="payment/method" xsi:type="string">banktransfer</data> - <data name="status" xsi:type="string">Precessing</data> + <data name="status" xsi:type="string">Processing</data> <data name="orderButtonsAvailable" xsi:type="string">Back, Send Email, Cancel, Hold, Invoice, Edit</data> <data name="configData" xsi:type="string">banktransfer_specificcountry_gb, can_subtract_and_can_back_in_stock</data> <constraint name="Magento\Shipping\Test\Constraint\AssertShipmentSuccessCreateMessage" /> @@ -102,10 +101,8 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderButtonsAvailable" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> - <data name="issue" xsi:type="string">MAGETWO-66737: Magento\Checkout\Test\TestCase\OnePageCheckoutTest with OnePageCheckoutTestVariation3 and 4 is not stable</data> </variation> <variation name="OnePageCheckoutTestVariation4" summary="One Page Checkout Products with Special Prices" ticketId="MAGETWO-12429"> - <data name="issue" xsi:type="string">MAGETWO-95659: Fix and Unskip MTF OnePageCheckoutOfflinePaymentMethodsTest</data> <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test, severity:S0</data> <data name="products/0" xsi:type="string">catalogProductSimple::product_with_special_price</data> <data name="products/1" xsi:type="string">configurableProduct::product_with_special_price</data> @@ -211,7 +208,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="OnePageCheckoutTestVariation9" summary="One Page Checkout Products with different shipping/billing address and Tier Prices" ticketId="MAGETWO-42604"> - <data name="tag" xsi:type="string">stable:no, severity:S1</data> + <data name="tag" xsi:type="string">severity:S1</data> <data name="products/0" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_order_qty_3</data> <data name="customer/dataset" xsi:type="string">default</data> <data name="checkoutMethod" xsi:type="string">login</data> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php index d951d84bab78d..f79cf8d7eb7fa 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php @@ -59,6 +59,13 @@ class SelectCheckoutMethodStep implements TestStepInterface */ private $customerAccountCreatePage; + /** + * Proceed to checkout from minicart step + * + * @var proceedToCheckoutFromMiniShoppingCartStep + */ + private $proceedToCheckoutFromMiniShoppingCartStep; + /** * @constructor * @param CheckoutOnepage $checkoutOnepage @@ -66,6 +73,7 @@ class SelectCheckoutMethodStep implements TestStepInterface * @param Customer $customer * @param LogoutCustomerOnFrontendStep $logoutCustomerOnFrontend * @param ClickProceedToCheckoutStep $clickProceedToCheckoutStep + * @param ProceedToCheckoutFromMiniShoppingCartStep $proceedToCheckoutFromMiniShoppingCartStep * @param string $checkoutMethod */ public function __construct( @@ -74,6 +82,7 @@ public function __construct( Customer $customer, LogoutCustomerOnFrontendStep $logoutCustomerOnFrontend, ClickProceedToCheckoutStep $clickProceedToCheckoutStep, + ProceedToCheckoutFromMiniShoppingCartStep $proceedToCheckoutFromMiniShoppingCartStep, $checkoutMethod ) { $this->checkoutOnepage = $checkoutOnepage; @@ -82,6 +91,7 @@ public function __construct( $this->logoutCustomerOnFrontend = $logoutCustomerOnFrontend; $this->clickProceedToCheckoutStep = $clickProceedToCheckoutStep; $this->checkoutMethod = $checkoutMethod; + $this->proceedToCheckoutFromMiniShoppingCartStep = $proceedToCheckoutFromMiniShoppingCartStep; } /** @@ -129,6 +139,7 @@ private function processRegister() if ($this->checkoutMethod === 'register_before_checkout') { $this->checkoutOnepage->getAuthenticationPopupBlock()->createAccount(); $this->customerAccountCreatePage->getRegisterForm()->registerCustomer($this->customer); + $this->proceedToCheckoutFromMiniShoppingCartStep->run(); } } From a0bb0fcf965d47f617cc801187f6290d8bdf22a6 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Thu, 1 Nov 2018 09:45:21 +0200 Subject: [PATCH 599/812] graphQl: updated shipping address coverage content --- .../MultiShipping.php | 69 ++++++++++++++++--- .../MultiShipping/ShippingItemsMapper.php | 43 ++++++++++++ .../SingleShipping.php | 47 +++++++++++-- .../SetShippingAddressesOnCart.php | 32 +++------ .../Magento/QuoteGraphQl/etc/schema.graphqls | 4 ++ 5 files changed, 157 insertions(+), 38 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php index 71560a26c03ee..318fd9361af5a 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php @@ -1,23 +1,76 @@ <?php /** - * @author Atwix Team - * @copyright Copyright (c) 2018 Atwix (https://www.atwix.com/) + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart; +use Magento\Authorization\Model\UserContextInterface; +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Multishipping\Model\Checkout\Type\Multishipping as MultishippingModel; +use Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\MultiShipping\ShippingItemsMapper; + class MultiShipping { /** + * @var MultishippingModel + */ + private $multishippingModel; + + /** + * @var ShippingItemsMapper + */ + private $shippingItemsInformationMapper; + + /** + * @param MultishippingModel $multishippingModel + * @param ShippingItemsMapper $shippingItemsInformationMapper + */ + public function __construct( + MultishippingModel $multishippingModel, + ShippingItemsMapper $shippingItemsInformationMapper + ) { + $this->multishippingModel = $multishippingModel; + $this->shippingItemsInformationMapper = $shippingItemsInformationMapper; + } + + /** + * @param ContextInterface $context * @param int $cartId - * @param array $cartItems - * @param int|null $customerAddressId - * @param array|null $address - * @return void + * @param array $shippingAddresses */ - public function setAddress(int $cartId, array $cartItems, ?int $customerAddressId, ?array $address): void + public function setAddresses(ContextInterface $context, int $cartId, array $shippingAddresses): void { - //TODO: implement multi shipping + if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { + throw new GraphQlAuthorizationException( + __( + 'Multishipping allowed only for authorized customers' + ) + ); + } + + $shippingItemsInformation = []; + foreach ($shippingAddresses as $shippingAddress) { + $customerAddressId = $shippingAddress['customer_address_id'] ?? null; + $cartItems = $shippingAddress['cart_items'] ?? null; + if (!$customerAddressId) { + throw new GraphQlInputException(__('Parameter "customer_address_id" is required for multishipping')); + } + if (!$cartItems) { + throw new GraphQlInputException(__('Parameter "cart_items" is required for multishipping')); + } + + $shippingItemsInformation = array_merge( + $shippingItemsInformation, + $this->shippingItemsInformationMapper->map($shippingAddress) + ); + } + + //TODO: multishipping model works with session. Do we need to avoid it? + $this->multishippingModel->setShippingItemsInformation($shippingItemsInformation); } } diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php new file mode 100644 index 0000000000000..c9cefc421a544 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\MultiShipping; + +/** + * Shipping address to shipping items mapper + */ +class ShippingItemsMapper +{ + + /** + * Converts shipping address input array into shipping items information array + * Array structure: + * array( + * $cartItemId => array( + * 'qty' => $qty, + * 'address' => $customerAddressId + * ) + * ) + * + * @param array $shippingAddress + * @return array + */ + public function map(array $shippingAddress): array + { + $shippingItemsInformation = []; + foreach ($shippingAddress['cart_items'] as $cartItem) { + $shippingItemsInformation[] = [ + $cartItem['cart_item_id'] => [ + 'qty' => $cartItem['quantity'], + 'address' => $shippingAddress['customer_address_id'] + ] + ]; + } + + return $shippingItemsInformation; + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php index 536a907541b1a..feeb333683f76 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php @@ -1,12 +1,17 @@ <?php /** - * @author Atwix Team - * @copyright Copyright (c) 2018 Atwix (https://www.atwix.com/) + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart; +use Magento\Authorization\Model\UserContextInterface; +use Magento\Customer\Api\Data\AddressInterface; +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\Customer\Api\AddressRepositoryInterface; @@ -44,18 +49,46 @@ public function __construct( } /** + * @param ContextInterface $context * @param int $cartId - * @param int|null $customerAddressId - * @param array|null $address + * @param array $shippingAddress * @return void */ - public function setAddress(int $cartId, ?int $customerAddressId, ?array $address): void + public function setAddress(ContextInterface $context, int $cartId, array $shippingAddress): void { - if($customerAddressId) { + $customerAddressId = $shippingAddress['customer_address_id'] ?? null; + $addressInput = $shippingAddress['address'] ?? null; + + if (!$customerAddressId && !$addressInput) { + throw new GraphQlInputException( + __('Shipping address should contain either "customer_address_id" or "address" input.') + ); + } + if ($customerAddressId && $addressInput) { + throw new GraphQlInputException( + __('Shipping address can\'t contain "customer_address_id" and "address" input at the same time.') + ); + } + if ($customerAddressId) { + if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { + throw new GraphQlAuthorizationException( + __( + 'Address management allowed only for authorized customers' + ) + ); + } + /** @var AddressInterface $customerAddress */ $customerAddress = $this->addressRepository->getById($customerAddressId); + if ($context->getUserId() !== (int)$customerAddress->getCustomerId()) { + throw new GraphQlInputException( + __( + 'Address is not applicable for current customer' + ) + ); + } $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); } else { - $shippingAddress = $this->addressModel->addData($address); + $shippingAddress = $this->addressModel->addData($addressInput); } $this->shippingAddressManagement->assign($cartId, $shippingAddress); diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php index f3960f66d2792..7ffa6c4950b3d 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php @@ -7,7 +7,6 @@ namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress; -use Magento\Framework\Api\DataObjectHelper; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -22,11 +21,6 @@ */ class SetShippingAddressesOnCart implements ResolverInterface { - /** - * @var DataObjectHelper - */ - private $dataObjectHelper; - /** * @var MaskedQuoteIdToQuoteIdInterface */ @@ -48,20 +42,17 @@ class SetShippingAddressesOnCart implements ResolverInterface private $shippingAddressManagement; /** - * @param DataObjectHelper $dataObjectHelper * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId * @param MultiShipping $multiShipping * @param SingleShipping $singleShipping * @param ShippingAddressManagementInterface $shippingAddressManagement */ public function __construct( - DataObjectHelper $dataObjectHelper, MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, MultiShipping $multiShipping, SingleShipping $singleShipping, - ShippingAddressManagementInterface $shippingAddressManagement + ShippingAddressManagementInterface $shippingAddressManagement ) { - $this->dataObjectHelper = $dataObjectHelper; $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; $this->multiShipping = $multiShipping; $this->singleShipping = $singleShipping; @@ -76,23 +67,18 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value if (!isset($args['input']['cart_id'])) { throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); } + if (!isset($args['input']['shipping_addresses'])) { + throw new GraphQlInputException(__('Required parameter "shipping_addresses" is missing')); + } + + $shippingAddressesInput = $args['input']['shipping_addresses']; $maskedCartId = $args['input']['cart_id']; $cartId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); - $customerAddressId = $args['input']['customer_address_id'] ?? null; - $address = $args['input']['address'] ?? null; - $cartItems = $args['input']['cart_items'] ?? []; - - if (!$customerAddressId && !$address) { - throw new GraphQlInputException(__('Query should contain either address id or address input.')); - } - - //TODO: how to determine whether is multi shipping or not - if (!$cartItems) { - //TODO: assign cart items - $this->singleShipping->setAddress($cartId, $customerAddressId, $address); + if (count($shippingAddressesInput) === 1) { + $this->singleShipping->setAddress($context, $cartId, current($shippingAddressesInput)); } else { - $this->multiShipping->setAddress($cartId, $cartItems, $customerAddressId, $address); + $this->multiShipping->setAddresses($context, $cartId, $shippingAddressesInput); } //TODO: implement Cart object in the separate resolver diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index d13240a23140b..d99182ed10988 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -16,6 +16,10 @@ type Mutation { input SetShippingAddressesOnCartInput { cart_id: String! + shipping_addresses: [ShippingAddressInput!]! +} + +input ShippingAddressInput { customer_address_id: Int # Can be provided in one-page checkout and is required for multi-shipping checkout address: CartAddressInput cart_items: [CartItemQuantityInput!] From 71983df468f7d5a9ff35e915c59d56c4d33a414b Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi <yevhenii.dumskyi@gmail.com> Date: Thu, 1 Nov 2018 10:50:59 +0200 Subject: [PATCH 600/812] Fix backward incompatibility --- .../Catalog/Model/Product/Gallery/Processor.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index 048ad55985b72..9cd5073f4357c 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -9,7 +9,7 @@ use Magento\Framework\Api\Data\ImageContentInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Filesystem\DriverInterface; +use Magento\Framework\App\ObjectManager; /** * Catalog product Media Gallery attribute processor. @@ -60,7 +60,7 @@ class Processor /** * @var \Magento\Framework\File\Mime */ - protected $mime; + private $mime; /** * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository @@ -68,7 +68,7 @@ class Processor * @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel - * @param \Magento\Framework\File\Mime $mime + * @param \Magento\Framework\File\Mime|null $mime * @throws \Magento\Framework\Exception\FileSystemException */ public function __construct( @@ -77,14 +77,14 @@ public function __construct( \Magento\Catalog\Model\Product\Media\Config $mediaConfig, \Magento\Framework\Filesystem $filesystem, \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel, - \Magento\Framework\File\Mime $mime + \Magento\Framework\File\Mime $mime = null ) { $this->attributeRepository = $attributeRepository; $this->fileStorageDb = $fileStorageDb; $this->mediaConfig = $mediaConfig; $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->resourceModel = $resourceModel; - $this->mime = $mime; + $this->mime = $mime ?: ObjectManager::getInstance()->get(\Magento\Framework\File\Mime::class); } /** From 75e2547a7835330128bdf79e37e314b25f1fc30d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20H=C3=BCbner?= <mjh@bergwerk.ag> Date: Mon, 20 Aug 2018 18:37:40 +0300 Subject: [PATCH 601/812] Prevent rendering of "Ship here" button to select a shipping item if it is already selected - checks if the item is selected, if it is it does not render the button - removes the css which hides the button currently, because it is not needed anymore --- .../template/shipping-address/address-renderer/default.html | 2 ++ .../web/css/source/module/checkout/_shipping.less | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html index 2a5dc27328a43..cf64c0140b955 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html @@ -35,7 +35,9 @@ click="editAddress"> <span translate="'Edit'"></span> </button> + <!-- ko if: (!isSelected()) --> <button type="button" click="selectAddress" class="action action-select-shipping-item"> <span translate="'Ship Here'"></span> </button> + <!-- /ko --> </div> diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less index 0a463a95e3182..158cb0ebc0ed1 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less @@ -98,11 +98,6 @@ text-align: center; top: 0; } - - .action-select-shipping-item { - &:extend(.abs-no-display-s all); - visibility: hidden; - } } } From a537b009bbece04073700df55bbd1a0abaf31821 Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Thu, 1 Nov 2018 11:32:05 +0200 Subject: [PATCH 602/812] MAGETWO-96026: Create MFTF test for MAGETWO-93973 --- ...gAndQuantityIncrementsWorkWithDecimalinventoryTest.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml index 7a774c585c9cd..e9158e91432fa 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml @@ -1,3 +1,11 @@ +<?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="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest"> From f359bbcd3d734f5296f88c7078c1a2b6c3b00017 Mon Sep 17 00:00:00 2001 From: Misha Medzhytov <mdg12v@gmail.com> Date: Sun, 2 Sep 2018 20:16:50 +0300 Subject: [PATCH 603/812] #17890: show correct text swatch values per store view --- app/code/Magento/Swatches/Helper/Data.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Swatches/Helper/Data.php b/app/code/Magento/Swatches/Helper/Data.php index 38879178235c0..ac19ad5116cc3 100644 --- a/app/code/Magento/Swatches/Helper/Data.php +++ b/app/code/Magento/Swatches/Helper/Data.php @@ -488,6 +488,8 @@ private function addFallbackOptions(array $fallbackValues, array $swatches) && $swatches[$optionId]['type'] === $optionsArray[$currentStoreId]['type'] ) { $swatches[$optionId] = $optionsArray[$currentStoreId]; + } elseif (isset($optionsArray[$currentStoreId])) { + $swatches[$optionId] = $optionsArray[$currentStoreId]; } elseif (isset($optionsArray[self::DEFAULT_STORE_ID])) { $swatches[$optionId] = $optionsArray[self::DEFAULT_STORE_ID]; } From e794db8b1a9fb3b456b1cdaac5303d1888fc9698 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Thu, 1 Nov 2018 12:59:38 +0300 Subject: [PATCH 604/812] MAGETWO-91649: Magento ignore store-level url_key of child category in URL rewrite process for global scope - Fixed integration test; --- .../Magento/Catalog/Controller/Adminhtml/CategoryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php index a6d03fcc200e2..dad4d21362a0a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php @@ -403,7 +403,7 @@ public function moveActionDataProvider() { return [ [400, 401, 'first_url_key', 402, 'second_url_key', false], - [400, 401, 'duplicated_url_key', 402, 'duplicated_url_key', true], + [400, 401, 'duplicated_url_key', 402, 'duplicated_url_key', false], [0, 401, 'first_url_key', 402, 'second_url_key', true], [400, 401, 'first_url_key', 0, 'second_url_key', true], ]; From 70f1c939381a9ae123770f80a27b3fcaaf6bfc83 Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Thu, 1 Nov 2018 12:02:49 +0200 Subject: [PATCH 605/812] MAGETWO-95692: [2.3] Value of Customer Address Attribute is not shown in the Customers grid --- .../Magento/Customer/Model/Indexer/Source.php | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Customer/Model/Indexer/Source.php b/app/code/Magento/Customer/Model/Indexer/Source.php index e4bf03e08a9ad..a8878e2084ea0 100644 --- a/app/code/Magento/Customer/Model/Indexer/Source.php +++ b/app/code/Magento/Customer/Model/Indexer/Source.php @@ -5,6 +5,7 @@ */ namespace Magento\Customer\Model\Indexer; +use Magento\Customer\Model\ResourceModel\Customer\Indexer\CollectionFactory; use Magento\Customer\Model\ResourceModel\Customer\Indexer\Collection; use Magento\Framework\App\ResourceConnection\SourceProviderInterface; use Traversable; @@ -25,11 +26,11 @@ class Source implements \IteratorAggregate, \Countable, SourceProviderInterface private $batchSize; /** - * @param \Magento\Customer\Model\ResourceModel\Customer\Indexer\CollectionFactory $collection + * @param CollectionFactory $collectionFactory * @param int $batchSize */ public function __construct( - \Magento\Customer\Model\ResourceModel\Customer\Indexer\CollectionFactory $collectionFactory, + CollectionFactory $collectionFactory, $batchSize = 10000 ) { $this->customerCollection = $collectionFactory->create(); @@ -37,7 +38,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getMainTable() { @@ -45,7 +46,7 @@ public function getMainTable() } /** - * {@inheritdoc} + * @inheritdoc */ public function getIdFieldName() { @@ -53,7 +54,7 @@ public function getIdFieldName() } /** - * {@inheritdoc} + * @inheritdoc */ public function addFieldToSelect($fieldName, $alias = null) { @@ -62,7 +63,7 @@ public function addFieldToSelect($fieldName, $alias = null) } /** - * {@inheritdoc} + * @inheritdoc */ public function getSelect() { @@ -70,7 +71,7 @@ public function getSelect() } /** - * {@inheritdoc} + * @inheritdoc */ public function addFieldToFilter($attribute, $condition = null) { @@ -79,7 +80,7 @@ public function addFieldToFilter($attribute, $condition = null) } /** - * @return int + * @inheritdoc */ public function count() { @@ -105,4 +106,28 @@ public function getIterator() $pageNumber++; } while ($pageNumber <= $lastPage); } + + /** + * Joins Attribute + * + * @param string $alias alias for the joined attribute + * @param string|\Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute + * @param string $bind attribute of the main entity to link with joined $filter + * @param string|null $filter primary key for the joined entity (entity_id default) + * @param string $joinType inner|left + * @param int|null $storeId + * @return void + * @throws \Magento\Framework\Exception\LocalizedException + * @see Collection::joinAttribute() + */ + public function joinAttribute( + string $alias, + $attribute, + string $bind, + ?string $filter = null, + string $joinType = 'inner', + ?int $storeId = null + ): void { + $this->customerCollection->joinAttribute($alias, $attribute, $bind, $filter, $joinType, $storeId); + } } From 7c86822387cbee24186a1746b373b2bfb381bed8 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Thu, 1 Nov 2018 12:17:26 +0200 Subject: [PATCH 606/812] magento/magento2#10440: [Forwardport] Missing $debugHintsPath when sending email via command. --- app/code/Magento/Developer/etc/di.xml | 8 ++++++++ app/code/Magento/Developer/etc/frontend/di.xml | 7 ------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Developer/etc/di.xml b/app/code/Magento/Developer/etc/di.xml index 21ecf10c1b1e7..98adcbb3a8295 100644 --- a/app/code/Magento/Developer/etc/di.xml +++ b/app/code/Magento/Developer/etc/di.xml @@ -240,4 +240,12 @@ </argument> </arguments> </type> + + <type name="Magento\Developer\Model\TemplateEngine\Plugin\DebugHints"> + <arguments> + <argument name="debugHintsPath" xsi:type="string">dev/debug/template_hints_storefront</argument> + <argument name="debugHintsWithParam" xsi:type="string">dev/debug/template_hints_storefront_show_with_parameter</argument> + <argument name="debugHintsParameter" xsi:type="string">dev/debug/template_hints_parameter_value</argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Developer/etc/frontend/di.xml b/app/code/Magento/Developer/etc/frontend/di.xml index 329c158d897a9..aa4b347260209 100644 --- a/app/code/Magento/Developer/etc/frontend/di.xml +++ b/app/code/Magento/Developer/etc/frontend/di.xml @@ -9,11 +9,4 @@ <type name="Magento\Framework\View\TemplateEngineFactory"> <plugin name="debug_hints" type="Magento\Developer\Model\TemplateEngine\Plugin\DebugHints" sortOrder="10"/> </type> - <type name="Magento\Developer\Model\TemplateEngine\Plugin\DebugHints"> - <arguments> - <argument name="debugHintsPath" xsi:type="string">dev/debug/template_hints_storefront</argument> - <argument name="debugHintsWithParam" xsi:type="string">dev/debug/template_hints_storefront_show_with_parameter</argument> - <argument name="debugHintsParameter" xsi:type="string">dev/debug/template_hints_parameter_value</argument> - </arguments> - </type> </config> From 7f1f133d8e1db7d15b9f12d76085f68cdfe94833 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Thu, 1 Nov 2018 14:24:34 +0200 Subject: [PATCH 607/812] ENGCOM-1928: Fix file name. --- .../Store/ViewModel/{Switcher.php => SwitcherUrlProvider.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/code/Magento/Store/ViewModel/{Switcher.php => SwitcherUrlProvider.php} (100%) diff --git a/app/code/Magento/Store/ViewModel/Switcher.php b/app/code/Magento/Store/ViewModel/SwitcherUrlProvider.php similarity index 100% rename from app/code/Magento/Store/ViewModel/Switcher.php rename to app/code/Magento/Store/ViewModel/SwitcherUrlProvider.php From 24b7d98215333a1fa391073420391fdd079034b5 Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh <nikita.shcherbatykh@transoftgroup.com> Date: Thu, 1 Nov 2018 15:41:58 +0200 Subject: [PATCH 608/812] MAGETWO-95753: [2.3] Cannot save product with Tier Prices --- app/code/Magento/Catalog/Helper/Data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Helper/Data.php b/app/code/Magento/Catalog/Helper/Data.php index c83eb70486c43..3e96763632830 100644 --- a/app/code/Magento/Catalog/Helper/Data.php +++ b/app/code/Magento/Catalog/Helper/Data.php @@ -413,7 +413,7 @@ public function getAttributeHiddenFields() /** * Retrieve Catalog Price Scope * - * @return int/null + * @return int|null */ public function getPriceScope(): ?int { From d353304c65bd9e8c9eff7841f3a6e4deec403e65 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 1 Nov 2018 15:50:10 +0200 Subject: [PATCH 609/812] MAGETWO-95798: All country state's are shown for USA when shipping form has custom address attributes. --- .../Checkout/Test/Mftf/Section/CheckoutShippingSection.xml | 1 + app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index 494a365ffd507..a8e0c5508ae06 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -32,5 +32,6 @@ <element name="firstShippingMethod" type="radio" selector="//*[@id='checkout-shipping-method-load']//input[@class='radio']"/> <element name="defaultShipping" type="button" selector=".billing-address-details"/> <element name="stateInput" type="input" selector="input[name=region]"/> + <element name="regionOptions" type="select" selector="select[name=region_id] option"/> </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml index d090620145105..2609106b1f19b 100755 --- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml @@ -32,6 +32,7 @@ <data key="vat_id">vatData</data> <data key="default_shipping">true</data> <data key="default_billing">true</data> + <data key="region_qty">66</data> </entity> <entity name="US_Address_TX" type="address"> <data key="firstname">John</data> From 099465aed038cbdf2884326d5915acd84867d6e0 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Thu, 1 Nov 2018 16:37:19 +0200 Subject: [PATCH 610/812] ENGCOM-3201: Updated integration test. --- .../testsuite/Magento/Customer/Controller/Section/LoadTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php index 3e086a89f8140..3563087d3722b 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php @@ -13,7 +13,7 @@ public function testLoadInvalidSection() $expected = [ 'message' => 'The "section<invalid" section source isn't supported.', ]; - $this->dispatch('/customer/section/load/?sections=section<invalid&update_section_id=false&_=147066166394'); + $this->dispatch('/customer/section/load/?sections=section<invalid&force_new_section_timestamp=false&_=147066166394'); self::assertEquals(json_encode($expected), $this->getResponse()->getBody()); } } From 0ae58d9b877fffedee4ba7eeb40331c63dfcc7a3 Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Thu, 1 Nov 2018 17:10:46 +0200 Subject: [PATCH 611/812] MAGETWO-96026: Create MFTF test for MAGETWO-93973 --- .../Catalog/Test/Mftf/Section/AdminProductFormSection.xml | 2 +- ...PricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml index 9ec0dbf9f262c..249610568aec7 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml @@ -28,7 +28,7 @@ <element name="advancedPricingLink" type="button" selector="button[data-index='advanced_pricing_button']"/> <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="advancedInventoryLink" type="input" selector="//button[contains(@data-index, 'advanced_inventory_button')]"/> + <element name="advancedInventoryLink" type="button" selector="//button[contains(@data-index, 'advanced_inventory_button')]"/> <element name="productStockStatus" type="select" selector="select[name='product[quantity_and_stock_status][is_in_stock]']"/> <element name="productWeight" type="input" selector=".admin__field[data-index=weight] input"/> <element name="productWeightSelect" type="select" selector="select[name='product[product_has_weight]']"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml index e9158e91432fa..9dbd2eb0c1fae 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml @@ -45,6 +45,7 @@ <!--Step3. Open *Advanced Pricing* pop-up (Click on *Advanced Pricing* link). Click on *Add* button. Fill *0.5* in *Quantity*--> <scrollTo selector="{{AdminProductFormSection.productName}}" stepKey="scrollToProductName"/> <click selector="{{AdminProductFormSection.advancedPricingLink}}" stepKey="clickOnAdvancedPricingLink1"/> + <waitForElement selector="{{AdminProductFormAdvancedPricingSection.customerGroupPriceAddButton}}" stepKey="waitForAddButton"/> <click selector="{{AdminProductFormAdvancedPricingSection.customerGroupPriceAddButton}}" stepKey="clickOnCustomerGroupPriceAddButton"/> <fillField selector="{{AdminProductFormAdvancedPricingSection.productTierPriceQtyInput('0')}}" userInput="0.5" stepKey="fillProductTierPriceQty"/> <!--Step4. Close *Advanced Pricing* (Click on button *Done*). Save *prod1* (Click on button *Save*)--> From 9c53b7ca5cf096a21bb33c0ec496e74bba7a7fd0 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Thu, 1 Nov 2018 17:22:32 +0200 Subject: [PATCH 612/812] magento-engcom/magento2ce#2299: Code style fixes --- .../Controller/Adminhtml/Bulk/Details.php | 2 +- .../Backend/App/Request/BackendValidator.php | 4 + .../Block/Widget/Grid/Column/Filter/Theme.php | 4 + .../Magento/Backend/Block/Widget/Tabs.php | 32 ++++++- .../Console/Command/AbstractCacheCommand.php | 4 +- .../Product/Initialization/Helper.php | 7 ++ .../Product/Initialization/HelperTest.php | 16 ++++ .../Model/Address/AbstractAddress.php | 20 ++++- .../Customer/Model/Metadata/Form/Text.php | 3 + .../Magento/Eav/Model/Attribute/Data/Text.php | 1 + .../Magento/Quote/Model/Quote/Address.php | 83 ++++++++++--------- .../Console/Command/ConfigSetCommand.php | 7 +- 12 files changed, 135 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php b/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php index 5571c20f526cc..a450187dd094b 100644 --- a/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php +++ b/app/code/Magento/AsynchronousOperations/Controller/Adminhtml/Bulk/Details.php @@ -8,7 +8,7 @@ /** * Class View Operation Details Controller */ -class Details extends \Magento\Backend\App\Action +class Details extends \Magento\Backend\App\Action implements \Magento\Framework\App\Action\HttpGetActionInterface { /** * @var \Magento\Framework\View\Result\PageFactory diff --git a/app/code/Magento/Backend/App/Request/BackendValidator.php b/app/code/Magento/Backend/App/Request/BackendValidator.php index eed4fbb643d3e..4d04d2fed8eb2 100644 --- a/app/code/Magento/Backend/App/Request/BackendValidator.php +++ b/app/code/Magento/Backend/App/Request/BackendValidator.php @@ -77,6 +77,8 @@ public function __construct( } /** + * Validate request + * * @param RequestInterface $request * @param ActionInterface $action * @@ -115,6 +117,8 @@ private function validateRequest( } /** + * Create exception + * * @param RequestInterface $request * @param ActionInterface $action * diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php index 5db5dc59b4e5b..a0907726ccc46 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php +++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Theme.php @@ -9,6 +9,9 @@ */ namespace Magento\Backend\Block\Widget\Grid\Column\Filter; +/** + * Theme grid filter + */ class Theme extends \Magento\Backend\Block\Widget\Grid\Column\Filter\AbstractFilter { /** @@ -55,6 +58,7 @@ public function getHtml() /** * Retrieve options set in column. + * * Or load if options was not set. * * @return array diff --git a/app/code/Magento/Backend/Block/Widget/Tabs.php b/app/code/Magento/Backend/Block/Widget/Tabs.php index b390e2fa7d150..c7c1f93e8ca73 100644 --- a/app/code/Magento/Backend/Block/Widget/Tabs.php +++ b/app/code/Magento/Backend/Block/Widget/Tabs.php @@ -8,6 +8,8 @@ use Magento\Backend\Block\Widget\Tab\TabInterface; /** + * Tabs widget + * * @api * @SuppressWarnings(PHPMD.NumberOfChildren) * @since 100.0.2 @@ -178,6 +180,8 @@ protected function _addTabByName($tab, $tabId) } /** + * Get active tab id + * * @return string */ public function getActiveTabId() @@ -187,6 +191,7 @@ public function getActiveTabId() /** * Set Active Tab + * * Tab has to be not hidden and can show * * @param string $tabId @@ -231,7 +236,7 @@ protected function _setActiveTab($tabId) } /** - * {@inheritdoc} + * @inheritdoc */ protected function _beforeToHtml() { @@ -282,6 +287,8 @@ private function reorderTabs() } /** + * Apply tabs order + * * @param array $orderByPosition * @param array $orderByIdentity * @@ -294,7 +301,7 @@ private function applyTabsCorrectOrder(array $orderByPosition, array $orderByIde /** * Rearrange the positions by using the after tag for each tab. * - * @var integer $position + * @var int $position * @var TabInterface $tab */ foreach ($orderByPosition as $position => $tab) { @@ -338,6 +345,8 @@ private function finalTabsSortOrder(array $orderByPosition) } /** + * Get js object name + * * @return string */ public function getJsObjectName() @@ -346,6 +355,8 @@ public function getJsObjectName() } /** + * Get tabs ids + * * @return string[] */ public function getTabsIds() @@ -358,6 +369,8 @@ public function getTabsIds() } /** + * Get tab id + * * @param \Magento\Framework\DataObject|TabInterface $tab * @param bool $withPrefix * @return string @@ -371,6 +384,8 @@ public function getTabId($tab, $withPrefix = true) } /** + * CVan show tab + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return bool */ @@ -383,6 +398,8 @@ public function canShowTab($tab) } /** + * Get tab is hidden + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return bool * @SuppressWarnings(PHPMD.BooleanGetMethodName) @@ -396,6 +413,8 @@ public function getTabIsHidden($tab) } /** + * Get tab url + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return string */ @@ -414,6 +433,8 @@ public function getTabUrl($tab) } /** + * Get tab title + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return string */ @@ -426,6 +447,8 @@ public function getTabTitle($tab) } /** + * Get tab class + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return string */ @@ -441,6 +464,8 @@ public function getTabClass($tab) } /** + * Get tab label + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return string */ @@ -453,6 +478,8 @@ public function getTabLabel($tab) } /** + * Get tab content + * * @param \Magento\Framework\DataObject|TabInterface $tab * @return string */ @@ -469,6 +496,7 @@ public function getTabContent($tab) /** * Mark tabs as dependent of each other + * * Arbitrary number of tabs can be specified, but at least two * * @param string $tabOneId diff --git a/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php b/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php index ecea5716f653d..11da740c46606 100644 --- a/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php +++ b/app/code/Magento/Backend/Console/Command/AbstractCacheCommand.php @@ -11,6 +11,8 @@ use Symfony\Component\Console\Input\InputOption; /** + * Abstract cache command + * * @api * @since 100.0.2 */ @@ -40,7 +42,7 @@ public function __construct(Manager $cacheManager) } /** - * {@inheritdoc} + * @inheritdoc */ protected function configure() { diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index 988d61986e3d2..f11d16755ef0d 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -19,6 +19,8 @@ use Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper\AttributeFilter; /** + * Product helper + * * @api * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 100.0.2 @@ -365,6 +367,8 @@ private function overwriteValue($optionId, $option, $overwriteOptions) } /** + * Get link resolver instance + * * @return LinkResolver * @deprecated 101.0.0 */ @@ -377,6 +381,8 @@ private function getLinkResolver() } /** + * Get DateTimeFilter instance + * * @return \Magento\Framework\Stdlib\DateTime\Filter\DateTime * @deprecated 101.0.0 */ @@ -391,6 +397,7 @@ private function getDateTimeFilter() /** * Remove ids of non selected websites from $websiteIds array and return filtered data + * * $websiteIds parameter expects array with website ids as keys and 1 (selected) or 0 (non selected) as values * Only one id (default website ID) will be set to $websiteIds array when the single store mode is turned on * diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php index ff44a91a64998..c889c58e3df3a 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php @@ -95,6 +95,11 @@ class HelperTest extends \PHPUnit\Framework\TestCase */ protected $attributeFilterMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $dateTimeFilterMock; + /** * @inheritdoc */ @@ -170,6 +175,11 @@ protected function setUp() $resolverProperty = $helperReflection->getProperty('linkResolver'); $resolverProperty->setAccessible(true); $resolverProperty->setValue($this->helper, $this->linkResolverMock); + + $this->dateTimeFilterMock = $this->createMock(\Magento\Framework\Stdlib\DateTime\Filter\DateTime::class); + $dateTimeFilterProperty = $helperReflection->getProperty('dateTimeFilter'); + $dateTimeFilterProperty->setAccessible(true); + $dateTimeFilterProperty->setValue($this->helper, $this->dateTimeFilterMock); } /** @@ -211,6 +221,12 @@ public function testInitialize( if (!empty($tierPrice)) { $productData = array_merge($productData, ['tier_price' => $tierPrice]); } + + $this->dateTimeFilterMock->expects($this->once()) + ->method('filter') + ->with($specialFromDate) + ->willReturn($specialFromDate); + $attributeNonDate = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php index 3ee284a705b16..8848fabb9ea1f 100644 --- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php +++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php @@ -271,7 +271,7 @@ public function setStreet($street) * Enforce format of the street field or other multiline custom attributes * * @param array|string $key - * @param null $value + * @param mixed $value * @return \Magento\Framework\DataObject */ public function setData($key, $value = null) @@ -286,6 +286,7 @@ public function setData($key, $value = null) /** * Check that address can have multiline attribute by this code (as street or some custom attribute) + * * @param string $code * @return bool */ @@ -403,6 +404,8 @@ public function getRegionCode() } /** + * Get region id + * * @return int */ public function getRegionId() @@ -425,6 +428,8 @@ public function getRegionId() } /** + * Get country + * * @return string */ public function getCountry() @@ -502,6 +507,8 @@ public function getConfig() } /** + * Before save handler + * * @return $this */ public function beforeSave() @@ -591,6 +598,8 @@ public function validate() } /** + * Create region instance + * * @return \Magento\Directory\Model\Region */ protected function _createRegionInstance() @@ -599,6 +608,8 @@ protected function _createRegionInstance() } /** + * Create country instance + * * @return \Magento\Directory\Model\Country */ protected function _createCountryInstance() @@ -608,6 +619,7 @@ protected function _createCountryInstance() /** * Unset Region from address + * * @return $this * @since 100.2.0 */ @@ -617,6 +629,8 @@ public function unsRegion() } /** + * Is company required + * * @return bool * @since 100.2.0 */ @@ -626,6 +640,8 @@ protected function isCompanyRequired() } /** + * Is telephone required + * * @return bool * @since 100.2.0 */ @@ -635,6 +651,8 @@ protected function isTelephoneRequired() } /** + * Is fax required + * * @return bool * @since 100.2.0 */ diff --git a/app/code/Magento/Customer/Model/Metadata/Form/Text.php b/app/code/Magento/Customer/Model/Metadata/Form/Text.php index dcd3bc93569a4..c639b607e279f 100644 --- a/app/code/Magento/Customer/Model/Metadata/Form/Text.php +++ b/app/code/Magento/Customer/Model/Metadata/Form/Text.php @@ -11,6 +11,9 @@ use Magento\Customer\Api\Data\AttributeMetadataInterface; use Magento\Framework\Api\ArrayObjectSearch; +/** + * Form Text metadata + */ class Text extends AbstractData { /** diff --git a/app/code/Magento/Eav/Model/Attribute/Data/Text.php b/app/code/Magento/Eav/Model/Attribute/Data/Text.php index a919a54cf6289..0a49e012690f6 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/Text.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/Text.php @@ -51,6 +51,7 @@ public function extractValue(RequestInterface $request) /** * Validate data + * * Return true or array of errors * * @param array|string $value diff --git a/app/code/Magento/Quote/Model/Quote/Address.php b/app/code/Magento/Quote/Model/Quote/Address.php index f34cfbbf5fd26..e311eb924dee4 100644 --- a/app/code/Magento/Quote/Model/Quote/Address.php +++ b/app/code/Magento/Quote/Model/Quote/Address.php @@ -965,6 +965,7 @@ public function collectShippingRates() /** * Request shipping rates for entire address or specified address item + * * Returns true if current selected shipping method code corresponds to one of the found rates * * @param \Magento\Quote\Model\Quote\Item\AbstractItem $item @@ -1348,7 +1349,7 @@ public function getAllBaseTotalAmounts() /******************************* End Total Collector Interface *******************************************/ /** - * {@inheritdoc} + * @inheritdoc */ protected function _getValidationRulesBeforeSave() { @@ -1356,7 +1357,7 @@ protected function _getValidationRulesBeforeSave() } /** - * {@inheritdoc} + * @inheritdoc */ public function getCountryId() { @@ -1364,7 +1365,7 @@ public function getCountryId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCountryId($countryId) { @@ -1372,7 +1373,7 @@ public function setCountryId($countryId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getStreet() { @@ -1381,7 +1382,7 @@ public function getStreet() } /** - * {@inheritdoc} + * @inheritdoc */ public function setStreet($street) { @@ -1389,7 +1390,7 @@ public function setStreet($street) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCompany() { @@ -1397,7 +1398,7 @@ public function getCompany() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCompany($company) { @@ -1405,7 +1406,7 @@ public function setCompany($company) } /** - * {@inheritdoc} + * @inheritdoc */ public function getTelephone() { @@ -1413,7 +1414,7 @@ public function getTelephone() } /** - * {@inheritdoc} + * @inheritdoc */ public function setTelephone($telephone) { @@ -1421,7 +1422,7 @@ public function setTelephone($telephone) } /** - * {@inheritdoc} + * @inheritdoc */ public function getFax() { @@ -1429,7 +1430,7 @@ public function getFax() } /** - * {@inheritdoc} + * @inheritdoc */ public function setFax($fax) { @@ -1437,7 +1438,7 @@ public function setFax($fax) } /** - * {@inheritdoc} + * @inheritdoc */ public function getPostcode() { @@ -1445,7 +1446,7 @@ public function getPostcode() } /** - * {@inheritdoc} + * @inheritdoc */ public function setPostcode($postcode) { @@ -1453,7 +1454,7 @@ public function setPostcode($postcode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCity() { @@ -1461,7 +1462,7 @@ public function getCity() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCity($city) { @@ -1469,7 +1470,7 @@ public function setCity($city) } /** - * {@inheritdoc} + * @inheritdoc */ public function getFirstname() { @@ -1477,7 +1478,7 @@ public function getFirstname() } /** - * {@inheritdoc} + * @inheritdoc */ public function setFirstname($firstname) { @@ -1485,7 +1486,7 @@ public function setFirstname($firstname) } /** - * {@inheritdoc} + * @inheritdoc */ public function getLastname() { @@ -1493,7 +1494,7 @@ public function getLastname() } /** - * {@inheritdoc} + * @inheritdoc */ public function setLastname($lastname) { @@ -1501,7 +1502,7 @@ public function setLastname($lastname) } /** - * {@inheritdoc} + * @inheritdoc */ public function getMiddlename() { @@ -1509,7 +1510,7 @@ public function getMiddlename() } /** - * {@inheritdoc} + * @inheritdoc */ public function setMiddlename($middlename) { @@ -1517,7 +1518,7 @@ public function setMiddlename($middlename) } /** - * {@inheritdoc} + * @inheritdoc */ public function getPrefix() { @@ -1525,7 +1526,7 @@ public function getPrefix() } /** - * {@inheritdoc} + * @inheritdoc */ public function setPrefix($prefix) { @@ -1533,7 +1534,7 @@ public function setPrefix($prefix) } /** - * {@inheritdoc} + * @inheritdoc */ public function getSuffix() { @@ -1541,7 +1542,7 @@ public function getSuffix() } /** - * {@inheritdoc} + * @inheritdoc */ public function setSuffix($suffix) { @@ -1549,7 +1550,7 @@ public function setSuffix($suffix) } /** - * {@inheritdoc} + * @inheritdoc */ public function getVatId() { @@ -1557,7 +1558,7 @@ public function getVatId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatId($vatId) { @@ -1565,7 +1566,7 @@ public function setVatId($vatId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCustomerId() { @@ -1573,7 +1574,7 @@ public function getCustomerId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomerId($customerId) { @@ -1581,7 +1582,7 @@ public function setCustomerId($customerId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getEmail() { @@ -1594,7 +1595,7 @@ public function getEmail() } /** - * {@inheritdoc} + * @inheritdoc */ public function setEmail($email) { @@ -1602,7 +1603,7 @@ public function setEmail($email) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegion($region) { @@ -1610,7 +1611,7 @@ public function setRegion($region) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegionId($regionId) { @@ -1618,7 +1619,7 @@ public function setRegionId($regionId) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegionCode($regionCode) { @@ -1626,7 +1627,7 @@ public function setRegionCode($regionCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function getSameAsBilling() { @@ -1634,7 +1635,7 @@ public function getSameAsBilling() } /** - * {@inheritdoc} + * @inheritdoc */ public function setSameAsBilling($sameAsBilling) { @@ -1642,7 +1643,7 @@ public function setSameAsBilling($sameAsBilling) } /** - * {@inheritdoc} + * @inheritdoc */ public function getCustomerAddressId() { @@ -1650,7 +1651,7 @@ public function getCustomerAddressId() } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomerAddressId($customerAddressId) { @@ -1681,7 +1682,7 @@ public function setSaveInAddressBook($saveInAddressBook) //@codeCoverageIgnoreEnd /** - * {@inheritdoc} + * @inheritdoc * * @return \Magento\Quote\Api\Data\AddressExtensionInterface|null */ @@ -1691,7 +1692,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} + * @inheritdoc * * @param \Magento\Quote\Api\Data\AddressExtensionInterface $extensionAttributes * @return $this @@ -1712,7 +1713,7 @@ public function getShippingMethod() } /** - * {@inheritdoc} + * @inheritdoc */ protected function getCustomAttributesCodes() { diff --git a/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php b/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php index 69c369f1ec9f6..e8ff8f09c345e 100644 --- a/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php +++ b/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php @@ -14,6 +14,9 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\Question; +/** + * Config Set Command + */ class ConfigSetCommand extends AbstractSetupCommand { /** @@ -68,7 +71,7 @@ protected function configure() } /** - * {@inheritdoc} + * @inheritdoc */ protected function execute(InputInterface $input, OutputInterface $output) { @@ -132,7 +135,7 @@ function ($value) { } /** - * {@inheritdoc} + * @inheritdoc */ protected function initialize(InputInterface $input, OutputInterface $output) { From 2beca3cec7c782ceff5b10eb9550a41fce4a479d Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Thu, 1 Nov 2018 17:40:35 +0200 Subject: [PATCH 613/812] ENGCOM-3063: Update colinmollenhour/cache-backend-redis from version 1.10.5 to 1.10.6 #18294 --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index c6d14eb38bc64..d4ac4fc091bbc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "49fe82043cd4ae944939b6cceade1d1b", + "content-hash": "78153b5c8150c0d145b3372a534a45eb", "packages": [ { "name": "braintree/braintree_php", @@ -88,16 +88,16 @@ }, { "name": "colinmollenhour/cache-backend-redis", - "version": "1.10.5", + "version": "1.10.6", "source": { "type": "git", "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis.git", - "reference": "91d949e28d939e607484a4bbf9307cff5afa689b" + "reference": "cc941a5f4cc017e11d3eab9061811ba9583ed6bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_Redis/zipball/91d949e28d939e607484a4bbf9307cff5afa689b", - "reference": "91d949e28d939e607484a4bbf9307cff5afa689b", + "url": "https://api.github.com/repos/colinmollenhour/Cm_Cache_Backend_Redis/zipball/cc941a5f4cc017e11d3eab9061811ba9583ed6bf", + "reference": "cc941a5f4cc017e11d3eab9061811ba9583ed6bf", "shasum": "" }, "require": { @@ -120,7 +120,7 @@ ], "description": "Zend_Cache backend using Redis with full support for tags.", "homepage": "https://github.com/colinmollenhour/Cm_Cache_Backend_Redis", - "time": "2018-05-15T16:02:25+00:00" + "time": "2018-09-24T16:02:07+00:00" }, { "name": "colinmollenhour/credis", From 210c4e15364e3a5303515c94906c0eccf9782871 Mon Sep 17 00:00:00 2001 From: Cezary Zeglen <cezary.zeglen@gmail.com> Date: Fri, 24 Aug 2018 17:18:40 +0200 Subject: [PATCH 614/812] Fix translations of category design theme not being applied --- app/code/Magento/Catalog/Model/Design.php | 13 ++++++++++++- .../testsuite/Magento/Catalog/Model/DesignTest.php | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Design.php b/app/code/Magento/Catalog/Model/Design.php index bd7cdabb40856..6c0629feaf6fd 100644 --- a/app/code/Magento/Catalog/Model/Design.php +++ b/app/code/Magento/Catalog/Model/Design.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Model; +use \Magento\Framework\TranslateInterface; + /** * Catalog Custom Category design Model * @@ -31,6 +33,11 @@ class Design extends \Magento\Framework\Model\AbstractModel */ protected $_localeDate; + /** + * @var TranslateInterface + */ + private $translator; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -47,10 +54,13 @@ public function __construct( \Magento\Framework\View\DesignInterface $design, \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, - array $data = [] + array $data = [], + TranslateInterface $translator = null ) { $this->_localeDate = $localeDate; $this->_design = $design; + $this->translator = $translator ?: + \Magento\Framework\App\ObjectManager::getInstance()->get(TranslateInterface::class); parent::__construct($context, $registry, $resource, $resourceCollection, $data); } @@ -63,6 +73,7 @@ public function __construct( public function applyCustomDesign($design) { $this->_design->setDesignTheme($design); + $this->translator->loadData(null, true); return $this; } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/DesignTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/DesignTest.php index 33f26302394f4..38960ab66399a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/DesignTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/DesignTest.php @@ -32,8 +32,12 @@ public function testApplyCustomDesign($theme) $design = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\Framework\View\DesignInterface::class ); + $translate = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Framework\TranslateInterface::class + ); $this->assertEquals('package', $design->getDesignTheme()->getPackageCode()); $this->assertEquals('theme', $design->getDesignTheme()->getThemeCode()); + $this->assertEquals('themepackage/theme', $translate->getTheme()); } /** From 52381c16a8af9255dc032f13aa80d0dce8d8cd53 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Thu, 1 Nov 2018 11:21:58 -0500 Subject: [PATCH 615/812] MAGETWO-96034: DB compare of upgrade vs fresh install has some inconsistent table schemas --- app/code/Magento/Customer/etc/db_schema.xml | 2 +- app/code/Magento/Integration/etc/db_schema.xml | 2 +- app/code/Magento/Sales/etc/db_schema.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/etc/db_schema.xml b/app/code/Magento/Customer/etc/db_schema.xml index b3c15799011a2..8178baef71abb 100644 --- a/app/code/Magento/Customer/etc/db_schema.xml +++ b/app/code/Magento/Customer/etc/db_schema.xml @@ -506,7 +506,7 @@ <column xsi:type="int" name="customer_id" padding="11" unsigned="false" nullable="true" identity="false" comment="Customer Id"/> <column xsi:type="varchar" name="session_id" nullable="true" length="64" comment="Session ID"/> - <column xsi:type="timestamp" name="last_visit_at" on_update="true" nullable="true" default="CURRENT_TIMESTAMP" + <column xsi:type="timestamp" name="last_visit_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Last Visit Time"/> <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="visitor_id"/> diff --git a/app/code/Magento/Integration/etc/db_schema.xml b/app/code/Magento/Integration/etc/db_schema.xml index c2c2cedc665fb..1f702bfe4bc7a 100644 --- a/app/code/Magento/Integration/etc/db_schema.xml +++ b/app/code/Magento/Integration/etc/db_schema.xml @@ -136,7 +136,7 @@ comment="User type (admin or customer)"/> <column xsi:type="smallint" name="failures_count" padding="5" unsigned="true" nullable="true" identity="false" default="0" comment="Number of failed authentication attempts in a row"/> - <column xsi:type="timestamp" name="lock_expires_at" on_update="true" nullable="true" default="CURRENT_TIMESTAMP" + <column xsi:type="timestamp" name="lock_expires_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Lock expiration time"/> <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="log_id"/> diff --git a/app/code/Magento/Sales/etc/db_schema.xml b/app/code/Magento/Sales/etc/db_schema.xml index 6847b4681de52..ced999bb86019 100644 --- a/app/code/Magento/Sales/etc/db_schema.xml +++ b/app/code/Magento/Sales/etc/db_schema.xml @@ -769,7 +769,7 @@ <column xsi:type="varchar" name="order_increment_id" nullable="false" length="32" comment="Order Increment Id"/> <column xsi:type="int" name="order_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Order Id"/> - <column xsi:type="timestamp" name="order_created_at" on_update="true" nullable="true" + <column xsi:type="timestamp" name="order_created_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" comment="Order Increment Id"/> <column xsi:type="varchar" name="customer_name" nullable="false" length="128" comment="Customer Name"/> <column xsi:type="decimal" name="total_qty" scale="4" precision="12" unsigned="false" nullable="true" From a0fddaa2777641013b57a62eac9649efc8d79fe8 Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Thu, 1 Nov 2018 18:45:27 +0200 Subject: [PATCH 616/812] MAGETWO-96026: Create MFTF test for MAGETWO-93973 --- ...ingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml index 9dbd2eb0c1fae..6eb78809b187d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml @@ -10,13 +10,13 @@ xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest"> <annotations> - <features value="Tiered pricing and quantity increments work with decimal inventory"/> + <features value="Catalog"/> <stories value="Tiered pricing and quantity increments work with decimal inventory"/> <title value="Tiered pricing and quantity increments work with decimal inventory"/> <description value="Tiered pricing and quantity increments work with decimal inventory"/> <severity value="CRITICAL"/> - <testCaseId value="MAGETWO-91178"/> - <group value="product"/> + <testCaseId value="MAGETWO-93973"/> + <group value="Catalog"/> </annotations> <before> <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> From 547c6fe2f67312c7ba70a8a91adb684766dae98b Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Thu, 1 Nov 2018 11:58:34 -0500 Subject: [PATCH 617/812] MAGETWO-95773: Credit memo is created instead of returning error via invoice refund API for Bundle product - use filtered collection for loop --- app/code/Magento/Sales/Model/Order/ItemRepository.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/ItemRepository.php b/app/code/Magento/Sales/Model/Order/ItemRepository.php index b1ff747d4f487..cdf5bdf99786e 100644 --- a/app/code/Magento/Sales/Model/Order/ItemRepository.php +++ b/app/code/Magento/Sales/Model/Order/ItemRepository.php @@ -229,7 +229,9 @@ private function addParentItem(OrderItemInterface $orderItem) if ($parentId = $orderItem->getParentItemId()) { $orderItem->setParentItem($this->get($parentId)); } else { - foreach ($orderItem->getOrder()->getAllItems() as $item) { + $orderCollection = $orderItem->getOrder()->getItemsCollection()->filterByParent($orderItem->getItemId()); + + foreach ($orderCollection->getItems() as $item) { if ($item->getParentItemId() === $orderItem->getItemId()) { $item->setParentItem($orderItem); } From 23ad12aee17c8d5f7c4a48ae76a85b458664b1fa Mon Sep 17 00:00:00 2001 From: Sven Reichel <github-sr@hotmail.com> Date: Thu, 1 Nov 2018 19:24:16 +0100 Subject: [PATCH 618/812] Fixed annotations for setData() setData() should return objects class - that inherits from --- app/code/Magento/Catalog/Model/AbstractModel.php | 2 +- app/code/Magento/Customer/Model/Address/AbstractAddress.php | 2 +- app/code/Magento/Sales/Model/Order/Address.php | 2 +- app/code/Magento/Widget/Block/BlockInterface.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/AbstractModel.php b/app/code/Magento/Catalog/Model/AbstractModel.php index 007635b124331..5faf6ccbcdef9 100644 --- a/app/code/Magento/Catalog/Model/AbstractModel.php +++ b/app/code/Magento/Catalog/Model/AbstractModel.php @@ -179,7 +179,7 @@ public function isLockedAttribute($attributeCode) * * @param string|array $key * @param mixed $value - * @return \Magento\Framework\DataObject + * @return $this */ public function setData($key, $value = null) { diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php index 3ee284a705b16..19f91953a074e 100644 --- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php +++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php @@ -272,7 +272,7 @@ public function setStreet($street) * * @param array|string $key * @param null $value - * @return \Magento\Framework\DataObject + * @return $this */ public function setData($key, $value = null) { diff --git a/app/code/Magento/Sales/Model/Order/Address.php b/app/code/Magento/Sales/Model/Order/Address.php index 77d8330a72550..8bc602c75db4d 100644 --- a/app/code/Magento/Sales/Model/Order/Address.php +++ b/app/code/Magento/Sales/Model/Order/Address.php @@ -174,7 +174,7 @@ protected function implodeStreetValue($value) * * @param array|string $key * @param null $value - * @return \Magento\Framework\DataObject + * @return $this */ public function setData($key, $value = null) { diff --git a/app/code/Magento/Widget/Block/BlockInterface.php b/app/code/Magento/Widget/Block/BlockInterface.php index ddf810f433f3a..db101b5e81adc 100644 --- a/app/code/Magento/Widget/Block/BlockInterface.php +++ b/app/code/Magento/Widget/Block/BlockInterface.php @@ -35,7 +35,7 @@ public function addData(array $arr); * * @param string|array $key * @param mixed $value - * @return \Magento\Framework\DataObject + * @return $this */ public function setData($key, $value = null); } From 2533e88aea6e5834f632ff631e5a4cce6e1496b0 Mon Sep 17 00:00:00 2001 From: Tommy Wiebell <twiebell@adobe.com> Date: Thu, 1 Nov 2018 16:27:20 -0500 Subject: [PATCH 619/812] MAGETWO-95773: Credit memo is created instead of returning error via invoice refund API for Bundle product - Update unit test coverage to include changed functionality --- .../Unit/Model/Order/ItemRepositoryTest.php | 94 ++++++++++++------- 1 file changed, 60 insertions(+), 34 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php index 5e1b49c0013e3..7f3626c25d8df 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php @@ -145,7 +145,7 @@ public function testGetEmptyEntity() $model->get($orderItemId); } - public function testGet() + public function testGetAsParentWithChild() { $orderItemId = 1; $productType = 'configurable'; @@ -154,18 +154,27 @@ public function testGet() $this->getProductOptionExtensionMock(); $productOption = $this->getProductOptionMock(); - $orderItemMock = $this->getOrderMock($productType, $productOption); + $orderItemMock = $this->getOrderItemMock($productType, $productOption); + + $orderItemCollectionMock = $this->createMock(\Magento\Sales\Model\ResourceModel\Order\Item\Collection::class); + $orderItemCollectionMock->expects($this->once()) + ->method('filterByParent') + ->with($orderItemId) + ->willReturnSelf(); + $orderItemCollectionMock->expects($this->once()) + ->method('getItems') + ->willReturn([$orderItemMock]); $orderMock = $this->createMock(\Magento\Sales\Model\Order::class); $orderMock->expects($this->once()) - ->method('getAllItems') - ->willReturn([$orderItemMock]); + ->method('getItemsCollection') + ->willReturn($orderItemCollectionMock); $orderItemMock->expects($this->once()) ->method('load') ->with($orderItemId) ->willReturn($orderItemMock); - $orderItemMock->expects($this->exactly(2)) + $orderItemMock->expects($this->exactly(3)) ->method('getItemId') ->willReturn($orderItemId); $orderItemMock->expects($this->once()) @@ -183,6 +192,45 @@ public function testGet() $this->assertSame($orderItemMock, $model->get($orderItemId)); } + public function testGetAsChild() + { + $orderItemId = 1; + $parentItemId = 66; + $productType = 'configurable'; + + $this->productOptionData = ['option1' => 'value1']; + + $this->getProductOptionExtensionMock(); + $productOption = $this->getProductOptionMock(); + $orderItemMock = $this->getOrderItemMock($productType, $productOption); + + $orderItemMock->expects($this->once()) + ->method('load') + ->with($orderItemId) + ->willReturn($orderItemMock); + $orderItemMock->expects($this->once()) + ->method('getItemId') + ->willReturn($orderItemId); + $orderItemMock->expects($this->exactly(3)) + ->method('getParentItemId') + ->willReturn($parentItemId); + + $this->metadata->expects($this->once()) + ->method('getNewInstance') + ->willReturn($orderItemMock); + + $parentItemMock = $this->createMock(\Magento\Sales\Model\Order\Item::class); + + $model = $this->getModel($orderItemMock, $productType); + $reflectedRegistryProperty = new \ReflectionProperty($model, 'registry'); + $reflectedRegistryProperty->setAccessible(true); + $reflectedRegistryProperty->setValue($model, [$parentItemId => $parentItemMock]); + $this->assertSame($orderItemMock, $model->get($orderItemId)); + + // Assert already registered + $this->assertSame($orderItemMock, $model->get($orderItemId)); + } + public function testGetList() { $productType = 'configurable'; @@ -192,7 +240,7 @@ public function testGetList() ->getMock(); $this->getProductOptionExtensionMock(); $productOption = $this->getProductOptionMock(); - $orderItemMock = $this->getOrderMock($productType, $productOption); + $orderItemMock = $this->getOrderItemMock($productType, $productOption); $searchResultMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Item\Collection::class) ->disableOriginalConstructor() @@ -214,35 +262,12 @@ public function testDeleteById() $orderItemId = 1; $productType = 'configurable'; - $requestMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->disableOriginalConstructor() - ->getMock(); - $orderItemMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class) ->disableOriginalConstructor() ->getMock(); - - $orderMock = $this->createMock(\Magento\Sales\Model\Order::class); - $orderMock->expects($this->once()) - ->method('getAllItems') - ->willReturn([$orderItemMock]); - $orderItemMock->expects($this->once()) - ->method('load') - ->with($orderItemId) - ->willReturn($orderItemMock); - $orderItemMock->expects($this->exactly(2)) - ->method('getItemId') + ->method('getEntityId') ->willReturn($orderItemId); - $orderItemMock->expects($this->once()) - ->method('getProductType') - ->willReturn($productType); - $orderItemMock->expects($this->once()) - ->method('getBuyRequest') - ->willReturn($requestMock); - $orderItemMock->expects($this->once()) - ->method('getOrder') - ->willReturn($orderMock); $orderItemResourceMock = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class) ->disableOriginalConstructor() @@ -252,15 +277,16 @@ public function testDeleteById() ->with($orderItemMock) ->willReturnSelf(); - $this->metadata->expects($this->once()) - ->method('getNewInstance') - ->willReturn($orderItemMock); $this->metadata->expects($this->exactly(1)) ->method('getMapper') ->willReturn($orderItemResourceMock); $model = $this->getModel($orderItemMock, $productType); + $reflectedRegistryProperty = new \ReflectionProperty($model, 'registry'); + $reflectedRegistryProperty->setAccessible(true); + $reflectedRegistryProperty->setValue($model, [$orderItemId => $orderItemMock]); $this->assertTrue($model->deleteById($orderItemId)); + $this->assertEmpty($reflectedRegistryProperty->getValue($model)); } /** @@ -318,7 +344,7 @@ protected function getModel( * @param \PHPUnit_Framework_MockObject_MockObject $productOption * @return \PHPUnit_Framework_MockObject_MockObject */ - protected function getOrderMock($productType, $productOption) + protected function getOrderItemMock($productType, $productOption) { $requestMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) ->disableOriginalConstructor() From ea661055fc94c1f5a3c7399463915491acc8c0a5 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 2 Nov 2018 11:41:20 +0300 Subject: [PATCH 620/812] MAGETWO-70303: [GITHUB] Anchor categories are showing products of disabled subcategories #9002 - Fix comments --- .../Catalog/Model/Indexer/Category/Product/AbstractAction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php index a1358c02ce9fc..178f4172ce6fa 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php @@ -605,7 +605,7 @@ protected function getTemporaryTreeIndexTableName() if (empty($this->tempTreeIndexTableName)) { $this->tempTreeIndexTableName = $this->connection->getTableName('temp_catalog_category_tree_index') . '_' - . substr(md5(time() . random_int(0, 999999999)), 0, 8); + . substr(sha1(time() . random_int(0, 999999999)), 0, 8); } return $this->tempTreeIndexTableName; From 480aa38783f28951ed10f16177aaf3f295818f9e Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 2 Nov 2018 11:53:15 +0300 Subject: [PATCH 621/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fix comments --- .../Magento/Catalog/Block/Product/ProductList/Toolbar.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index c7a9fcce7bf7a..a2cbc5087cd12 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -161,10 +161,10 @@ public function __construct( \Magento\Framework\Url\EncoderInterface $urlEncoder, ProductList $productListHelper, \Magento\Framework\Data\Helper\PostHelper $postDataHelper, + array $data = [], ToolbarMemorizer $toolbarMemorizer = null, \Magento\Framework\App\Http\Context $httpContext = null, - \Magento\Framework\Data\Form\FormKey $formKey = null, - array $data = [] + \Magento\Framework\Data\Form\FormKey $formKey = null ) { $this->_catalogSession = $catalogSession; $this->_catalogConfig = $catalogConfig; From 0cf59de0e706b213e836949700a713fdfa9cf4f4 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 2 Nov 2018 11:33:02 +0200 Subject: [PATCH 622/812] Added user permission check --- .../Model/Resolver/CartAddress.php | 30 +++++++++++++++---- .../SetShippingMethodsOnCart.php | 8 +++-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php index f83a112ba5ba8..d2b502688adbc 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php @@ -10,11 +10,13 @@ use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Model\MaskedQuoteIdToQuoteId; +use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser; use Magento\QuoteGraphQl\Model\Resolver\Address\AddressDataProvider; /** @@ -27,6 +29,11 @@ class CartAddress implements ResolverInterface */ private $addressDataProvider; + /** + * @var IsCartMutationAllowedForCurrentUser + */ + private $isCartMutationAllowedForCurrentUser; + /** * @var CartRepositoryInterface */ @@ -43,15 +50,18 @@ class CartAddress implements ResolverInterface * @param MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId * @param CartRepositoryInterface $cartRepository * @param AddressDataProvider $addressDataProvider + * @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser */ public function __construct( MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId, CartRepositoryInterface $cartRepository, - AddressDataProvider $addressDataProvider + AddressDataProvider $addressDataProvider, + IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser ) { $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; $this->cartRepository = $cartRepository; $this->addressDataProvider = $addressDataProvider; + $this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser; } /** @@ -59,20 +69,30 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { + /* The cart_id is used instead of the model because some parent resolvers do not work + with cart model */ if (!isset($value['cart_id'])) { - // TODO: consider the possibility to pass quote model instead od quote ID throw new LocalizedException(__('"cart_id" value should be specified')); } + $maskedCartId = $value['cart_id']; + try { - $quoteId = $this->maskedQuoteIdToQuoteId->execute($value['cart_id']); + $quoteId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); } catch (NoSuchEntityException $exception) { throw new GraphQlNoSuchEntityException( - __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $value['cart_id']]) + __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $maskedCartId]) ); } - // TODO: should we check customer permissions here as well? + if (false === $this->isCartMutationAllowedForCurrentUser->execute($quoteId)) { + throw new GraphQlAuthorizationException( + __( + 'The current user cannot perform operations on cart "%masked_cart_id"', + ['masked_cart_id' => $maskedCartId] + ) + ); + } try { $quote = $this->cartRepository->get($quoteId); diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php index 1f35f37d9cf23..7e35f97d9f711 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php @@ -72,13 +72,17 @@ class SetShippingMethodsOnCart implements ResolverInterface * @param ArrayManager $arrayManager * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId * @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser + * @param ShippingInformationManagementInterface $shippingInformationManagement + * @param QuoteAddressFactory $quoteAddressFactory + * @param QuoteAddressResource $quoteAddressResource + * @param ShippingInformationFactory $shippingInformationFactory */ public function __construct( ArrayManager $arrayManager, MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser, ShippingInformationManagementInterface $shippingInformationManagement, - QuoteAddressFactory $quoteAddressFacrory, + QuoteAddressFactory $quoteAddressFactory, QuoteAddressResource $quoteAddressResource, ShippingInformationFactory $shippingInformationFactory ) { @@ -88,7 +92,7 @@ public function __construct( $this->shippingInformationManagement = $shippingInformationManagement; $this->quoteAddressResource = $quoteAddressResource; - $this->quoteAddressFactory = $quoteAddressFacrory; + $this->quoteAddressFactory = $quoteAddressFactory; $this->shippingInformationFactory = $shippingInformationFactory; } From 5c0bcfd2160d549c082d7f51df0562ab674a9fe6 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 2 Nov 2018 11:58:47 +0200 Subject: [PATCH 623/812] Refactored flow for new authorization check logic --- .../Model/Resolver/CartAddress.php | 49 ++--------------- .../SetShippingMethodsOnCart.php | 52 +++++-------------- 2 files changed, 19 insertions(+), 82 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php index d2b502688adbc..54bd8fa2a5717 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php @@ -8,15 +8,11 @@ namespace Magento\QuoteGraphQl\Model\Resolver; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; -use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Model\MaskedQuoteIdToQuoteId; -use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser; use Magento\QuoteGraphQl\Model\Resolver\Address\AddressDataProvider; /** @@ -29,11 +25,6 @@ class CartAddress implements ResolverInterface */ private $addressDataProvider; - /** - * @var IsCartMutationAllowedForCurrentUser - */ - private $isCartMutationAllowedForCurrentUser; - /** * @var CartRepositoryInterface */ @@ -50,18 +41,15 @@ class CartAddress implements ResolverInterface * @param MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId * @param CartRepositoryInterface $cartRepository * @param AddressDataProvider $addressDataProvider - * @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser */ public function __construct( MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId, CartRepositoryInterface $cartRepository, - AddressDataProvider $addressDataProvider, - IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser + AddressDataProvider $addressDataProvider ) { $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; $this->cartRepository = $cartRepository; $this->addressDataProvider = $addressDataProvider; - $this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser; } /** @@ -69,39 +57,12 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - /* The cart_id is used instead of the model because some parent resolvers do not work - with cart model */ - if (!isset($value['cart_id'])) { - throw new LocalizedException(__('"cart_id" value should be specified')); + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); } - $maskedCartId = $value['cart_id']; - - try { - $quoteId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); - } catch (NoSuchEntityException $exception) { - throw new GraphQlNoSuchEntityException( - __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $maskedCartId]) - ); - } - - if (false === $this->isCartMutationAllowedForCurrentUser->execute($quoteId)) { - throw new GraphQlAuthorizationException( - __( - 'The current user cannot perform operations on cart "%masked_cart_id"', - ['masked_cart_id' => $maskedCartId] - ) - ); - } - - try { - $quote = $this->cartRepository->get($quoteId); - } catch (NoSuchEntityException $exception) { - throw new GraphQlNoSuchEntityException( - __('Could not find a cart with ID "%quote_id"', ['quote_id' => $quoteId]) - ); - } + $cart = $value['model']; - return $this->addressDataProvider->getCartAddresses($quote); + return $this->addressDataProvider->getCartAddresses($cart); } } diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php index 7e35f97d9f711..97a7bcea8aa48 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php @@ -12,18 +12,16 @@ use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\Stdlib\ArrayManager; -use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; -use Magento\QuoteGraphQl\Model\Authorization\IsCartMutationAllowedForCurrentUser; use Magento\Quote\Model\Quote\AddressFactory as QuoteAddressFactory; use Magento\Quote\Model\ResourceModel\Quote\Address as QuoteAddressResource; use Magento\Checkout\Model\ShippingInformationFactory; +use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; /** * Class SetShippingMethodsOnCart @@ -47,20 +45,15 @@ class SetShippingMethodsOnCart implements ResolverInterface */ private $quoteAddressResource; - /** - * @var MaskedQuoteIdToQuoteIdInterface - */ - private $maskedQuoteIdToQuoteId; - /** * @var ArrayManager */ private $arrayManager; /** - * @var IsCartMutationAllowedForCurrentUser + * @var GetCartForUser */ - private $isCartMutationAllowedForCurrentUser; + private $getCartForUser; /** * @var ShippingInformationManagementInterface @@ -70,8 +63,7 @@ class SetShippingMethodsOnCart implements ResolverInterface /** * SetShippingMethodsOnCart constructor. * @param ArrayManager $arrayManager - * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId - * @param IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser + * @param GetCartForUser $getCartForUser * @param ShippingInformationManagementInterface $shippingInformationManagement * @param QuoteAddressFactory $quoteAddressFactory * @param QuoteAddressResource $quoteAddressResource @@ -79,18 +71,15 @@ class SetShippingMethodsOnCart implements ResolverInterface */ public function __construct( ArrayManager $arrayManager, - MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, - IsCartMutationAllowedForCurrentUser $isCartMutationAllowedForCurrentUser, + GetCartForUser $getCartForUser, ShippingInformationManagementInterface $shippingInformationManagement, QuoteAddressFactory $quoteAddressFactory, QuoteAddressResource $quoteAddressResource, ShippingInformationFactory $shippingInformationFactory ) { $this->arrayManager = $arrayManager; - $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->isCartMutationAllowedForCurrentUser = $isCartMutationAllowedForCurrentUser; + $this->getCartForUser = $getCartForUser; $this->shippingInformationManagement = $shippingInformationManagement; - $this->quoteAddressResource = $quoteAddressResource; $this->quoteAddressFactory = $quoteAddressFactory; $this->shippingInformationFactory = $shippingInformationFactory; @@ -111,34 +100,20 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value throw new GraphQlInputException(__('Required parameter "shipping_methods" is missing')); } - $shippingMethod = reset($shippingMethods); // TODO: provide implementation for multishipping + $shippingMethod = reset($shippingMethods); if (!$shippingMethod['cart_address_id']) { throw new GraphQlInputException(__('Required parameter "cart_address_id" is missing')); } - if (!$shippingMethod['shipping_carrier_code']) { // FIXME: check the E_WARNING here + if (!$shippingMethod['shipping_carrier_code']) { throw new GraphQlInputException(__('Required parameter "shipping_carrier_code" is missing')); } - if (!$shippingMethod['shipping_method_code']) { // FIXME: check the E_WARNING here + if (!$shippingMethod['shipping_method_code']) { throw new GraphQlInputException(__('Required parameter "shipping_method_code" is missing')); } - try { - $cartId = $this->maskedQuoteIdToQuoteId->execute((string) $maskedCartId); - } catch (NoSuchEntityException $exception) { - throw new GraphQlNoSuchEntityException( - __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $maskedCartId]) - ); - } - - if (false === $this->isCartMutationAllowedForCurrentUser->execute($cartId)) { - throw new GraphQlAuthorizationException( - __( - 'The current user cannot perform operations on cart "%masked_cart_id"', - ['masked_cart_id' => $maskedCartId] - ) - ); - } + $userId = $context->getUserId(); + $cart = $this->getCartForUser->execute((string) $maskedCartId, $userId); $quoteAddress = $this->quoteAddressFactory->create(); $this->quoteAddressResource->load($quoteAddress, $shippingMethod['cart_address_id']); @@ -153,7 +128,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $shippingInformation->setShippingMethodCode($shippingMethod['shipping_method_code']); try { - $this->shippingInformationManagement->saveAddressInformation($cartId, $shippingInformation); + $this->shippingInformationManagement->saveAddressInformation($cart->getId(), $shippingInformation); } catch (NoSuchEntityException $exception) { throw new GraphQlNoSuchEntityException(__($exception->getMessage())); } catch (StateException $exception) { @@ -164,7 +139,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value return [ 'cart' => [ - 'cart_id' => $maskedCartId + 'cart_id' => $maskedCartId, + 'model' => $cart ] ]; } From c98c3d5142d73789e8233deb4aa90f172d716c21 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 2 Nov 2018 12:29:44 +0200 Subject: [PATCH 624/812] Logic for setting shipping method is moved to a separate class --- .../SetShippingMethodOnCart.php} | 84 ++++------------ .../Resolver/SetShippingMethodsOnCart.php | 99 +++++++++++++++++++ .../Magento/QuoteGraphQl/etc/schema.graphqls | 2 +- 3 files changed, 119 insertions(+), 66 deletions(-) rename app/code/Magento/QuoteGraphQl/Model/{Resolver/ShippingMethod/SetShippingMethodsOnCart.php => Cart/SetShippingMethodOnCart.php} (54%) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingMethodsOnCart.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php similarity index 54% rename from app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php rename to app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php index 97a7bcea8aa48..7f945dca2fd76 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingMethod/SetShippingMethodsOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php @@ -5,30 +5,26 @@ */ declare(strict_types=1); -namespace Magento\QuoteGraphQl\Model\Resolver\ShippingMethod; +namespace Magento\QuoteGraphQl\Model\Cart; -use Magento\Checkout\Api\ShippingInformationManagementInterface; -use Magento\Checkout\Model\ShippingInformation; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Framework\Stdlib\ArrayManager; +use Magento\Quote\Model\Quote; use Magento\Quote\Model\Quote\AddressFactory as QuoteAddressFactory; use Magento\Quote\Model\ResourceModel\Quote\Address as QuoteAddressResource; use Magento\Checkout\Model\ShippingInformationFactory; -use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; +use Magento\Checkout\Api\ShippingInformationManagementInterface; +use Magento\Checkout\Model\ShippingInformation; /** * Class SetShippingMethodsOnCart * - * Mutation resolver for setting shipping methods for shopping cart + * Set shipping method for a specified shopping cart address */ -class SetShippingMethodsOnCart implements ResolverInterface +class SetShippingMethodOnCart { /** * @var ShippingInformationFactory @@ -45,40 +41,23 @@ class SetShippingMethodsOnCart implements ResolverInterface */ private $quoteAddressResource; - /** - * @var ArrayManager - */ - private $arrayManager; - - /** - * @var GetCartForUser - */ - private $getCartForUser; - /** * @var ShippingInformationManagementInterface */ private $shippingInformationManagement; /** - * SetShippingMethodsOnCart constructor. - * @param ArrayManager $arrayManager - * @param GetCartForUser $getCartForUser * @param ShippingInformationManagementInterface $shippingInformationManagement * @param QuoteAddressFactory $quoteAddressFactory * @param QuoteAddressResource $quoteAddressResource * @param ShippingInformationFactory $shippingInformationFactory */ public function __construct( - ArrayManager $arrayManager, - GetCartForUser $getCartForUser, ShippingInformationManagementInterface $shippingInformationManagement, QuoteAddressFactory $quoteAddressFactory, QuoteAddressResource $quoteAddressResource, ShippingInformationFactory $shippingInformationFactory ) { - $this->arrayManager = $arrayManager; - $this->getCartForUser = $getCartForUser; $this->shippingInformationManagement = $shippingInformationManagement; $this->quoteAddressResource = $quoteAddressResource; $this->quoteAddressFactory = $quoteAddressFactory; @@ -86,37 +65,19 @@ public function __construct( } /** - * @inheritdoc + * Sets shipping method for a specified shopping cart address + * + * @param Quote $cart + * @param int $cartAddressId + * @param string $carrierCode + * @param string $methodCode + * @throws GraphQlInputException + * @throws GraphQlNoSuchEntityException */ - public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + public function execute(Quote $cart, int $cartAddressId, string $carrierCode, string $methodCode): void { - $shippingMethods = $this->arrayManager->get('input/shipping_methods', $args); - $maskedCartId = $this->arrayManager->get('input/cart_id', $args); - - if (!$maskedCartId) { - throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); - } - if (!$shippingMethods) { - throw new GraphQlInputException(__('Required parameter "shipping_methods" is missing')); - } - - $shippingMethod = reset($shippingMethods); - - if (!$shippingMethod['cart_address_id']) { - throw new GraphQlInputException(__('Required parameter "cart_address_id" is missing')); - } - if (!$shippingMethod['shipping_carrier_code']) { - throw new GraphQlInputException(__('Required parameter "shipping_carrier_code" is missing')); - } - if (!$shippingMethod['shipping_method_code']) { - throw new GraphQlInputException(__('Required parameter "shipping_method_code" is missing')); - } - - $userId = $context->getUserId(); - $cart = $this->getCartForUser->execute((string) $maskedCartId, $userId); - $quoteAddress = $this->quoteAddressFactory->create(); - $this->quoteAddressResource->load($quoteAddress, $shippingMethod['cart_address_id']); + $this->quoteAddressResource->load($quoteAddress, $cartAddressId); /** @var ShippingInformation $shippingInformation */ $shippingInformation = $this->shippingInformationFactory->create(); @@ -124,8 +85,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value /* If the address is not a shipping address (but billing) the system will find the proper shipping address for the selected cart and set the information there (actual for single shipping address) */ $shippingInformation->setShippingAddress($quoteAddress); - $shippingInformation->setShippingCarrierCode($shippingMethod['shipping_carrier_code']); - $shippingInformation->setShippingMethodCode($shippingMethod['shipping_method_code']); + $shippingInformation->setShippingCarrierCode($carrierCode); + $shippingInformation->setShippingMethodCode($methodCode); try { $this->shippingInformationManagement->saveAddressInformation($cart->getId(), $shippingInformation); @@ -136,12 +97,5 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value } catch (InputException $exception) { throw new GraphQlInputException(__($exception->getMessage())); } - - return [ - 'cart' => [ - 'cart_id' => $maskedCartId, - 'model' => $cart - ] - ]; } -} +} \ No newline at end of file diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingMethodsOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingMethodsOnCart.php new file mode 100644 index 0000000000000..920829f5d67b1 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingMethodsOnCart.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\Stdlib\ArrayManager; +use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; +use Magento\QuoteGraphQl\Model\Cart\SetShippingMethodOnCart; + +/** + * Class SetShippingMethodsOnCart + * + * Mutation resolver for setting shipping methods for shopping cart + */ +class SetShippingMethodsOnCart implements ResolverInterface +{ + /** + * @var SetShippingMethodOnCart + */ + private $setShippingMethodOnCart; + + /** + * @var ArrayManager + */ + private $arrayManager; + + /** + * @var GetCartForUser + */ + private $getCartForUser; + + /** + * @param ArrayManager $arrayManager + * @param GetCartForUser $getCartForUser + * @param SetShippingMethodOnCart $setShippingMethodOnCart + */ + public function __construct( + ArrayManager $arrayManager, + GetCartForUser $getCartForUser, + SetShippingMethodOnCart $setShippingMethodOnCart + ) { + $this->arrayManager = $arrayManager; + $this->getCartForUser = $getCartForUser; + $this->setShippingMethodOnCart = $setShippingMethodOnCart; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + $shippingMethods = $this->arrayManager->get('input/shipping_methods', $args); + $maskedCartId = $this->arrayManager->get('input/cart_id', $args); + + if (!$maskedCartId) { + throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); + } + if (!$shippingMethods) { + throw new GraphQlInputException(__('Required parameter "shipping_methods" is missing')); + } + + $shippingMethod = reset($shippingMethods); // This point can be extended for multishipping + + if (!$shippingMethod['cart_address_id']) { + throw new GraphQlInputException(__('Required parameter "cart_address_id" is missing')); + } + if (!$shippingMethod['shipping_carrier_code']) { + throw new GraphQlInputException(__('Required parameter "shipping_carrier_code" is missing')); + } + if (!$shippingMethod['shipping_method_code']) { + throw new GraphQlInputException(__('Required parameter "shipping_method_code" is missing')); + } + + $userId = $context->getUserId(); + $cart = $this->getCartForUser->execute((string) $maskedCartId, $userId); + + $this->setShippingMethodOnCart->execute( + $cart, + $shippingMethod['cart_address_id'], + $shippingMethod['shipping_carrier_code'], + $shippingMethod['shipping_method_code'] + ); + + return [ + 'cart' => [ + 'cart_id' => $maskedCartId, + 'model' => $cart + ] + ]; + } +} diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index cbc56bfaea66f..ce982952f1aee 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -11,7 +11,7 @@ type Mutation { removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveCouponFromCart") setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput - setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ShippingMethod\\SetShippingMethodsOnCart") + setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingMethodsOnCart") addSimpleProductsToCart(input: AddSimpleProductsToCartInput): AddSimpleProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddSimpleProductsToCart") } From c8dbdf4a1b94c5d3f6b9f3211f270c0168d74396 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Fri, 2 Nov 2018 12:37:27 +0200 Subject: [PATCH 625/812] graphQl: fixed multi shipping model --- .../MultiShipping/ShippingItemsMapper.php | 2 +- .../Magento/QuoteGraphQl/etc/graphql/di.xml | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/QuoteGraphQl/etc/graphql/di.xml diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php index c9cefc421a544..ad5207814db7c 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php @@ -14,7 +14,7 @@ class ShippingItemsMapper { /** - * Converts shipping address input array into shipping items information array + * Converts shipping address input array into shipping items information array * Array structure: * array( * $cartItemId => array( diff --git a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml new file mode 100644 index 0000000000000..43941c9740048 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml @@ -0,0 +1,26 @@ +<?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="multishippingPaymentSpecification" type="Magento\Payment\Model\Method\Specification\Composite"> + <arguments> + <argument name="specifications" xsi:type="array"> + <item name="enabled" xsi:type="string">Magento\Multishipping\Model\Payment\Method\Specification\Enabled</item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Multishipping\Block\Checkout\Billing"> + <arguments> + <argument name="paymentSpecification" xsi:type="object">multishippingPaymentSpecification</argument> + </arguments> + </type> + <type name="Magento\Multishipping\Model\Checkout\Type\Multishipping"> + <arguments> + <argument name="paymentSpecification" xsi:type="object">multishippingPaymentSpecification</argument> + </arguments> + </type> +</config> From ed26e551c5f54ead331d0187316269eddc3dff74 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 2 Nov 2018 13:05:17 +0200 Subject: [PATCH 626/812] #18562 - Internet Explorer 11: Edit customer in backend leads sometimes to a "loading circle" and error object does not support method "includes" --- app/code/Magento/Ui/view/base/web/js/form/element/country.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/country.js b/app/code/Magento/Ui/view/base/web/js/form/element/country.js index f64a80bf535ec..c75301018e190 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/country.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/country.js @@ -49,7 +49,7 @@ define([ if (!this.value()) { defaultCountry = _.filter(result, function (item) { - return item['is_default'] && item['is_default'].includes(value); + return item['is_default'] && _.contains(item['is_default'], value); }); if (defaultCountry.length) { From 388fb45eb6ff24b3fe9fc1452bf75db5507ae87c Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Fri, 2 Nov 2018 13:42:44 +0200 Subject: [PATCH 627/812] magento/magento2#17833: Child theme does not inherit translations from parent theme --- lib/internal/Magento/Framework/Translate.php | 76 ++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index ffa8e25031064..3d5213cb2a40e 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Framework; @@ -339,16 +340,21 @@ protected function _addData($data) } /** - * Load current theme translation + * Load current theme translation according to fallback * * @return $this */ protected function _loadThemeTranslation() { - $file = $this->_getThemeTranslationFile($this->getLocale()); - if ($file) { - $this->_addData($this->_getFileData($file)); + $themeFiles = $this->getThemeTranslationFilesList($this->getLocale()); + + /** @var string $file */ + foreach ($themeFiles as $file) { + if ($file) { + $this->_addData($this->_getFileData($file)); + } } + return $this; } @@ -389,11 +395,73 @@ protected function _getModuleTranslationFile($moduleName, $locale) return $file; } + /** + * Get theme translation locale file name + * + * @param string $locale + * @param array $config + * @return string + */ + private function getThemeTranslationFileName(string $locale, array $config): string + { + return $this->_viewFileSystem->getLocaleFileName( + 'i18n' . '/' . $locale . '.csv', + $config + ); + } + + /** + * Get parent themes for the current theme in fallback order + * + * @return array + */ + private function getParentThemesList(): array + { + $themes = []; + + $parentTheme = $this->_viewDesign->getDesignTheme()->getParentTheme(); + while($parentTheme) { + $themes[] = $parentTheme; + $parentTheme = $parentTheme->getParentTheme(); + } + $themes = array_reverse($themes); + + return $themes; + } + + /** + * Retrieve translation files for themes according to fallback + * + * @param string $locale + * + * @return array + */ + private function getThemeTranslationFilesList($locale): array + { + $translationFiles = []; + + /** @var \Magento\Framework\View\Design\ThemeInterface $theme */ + foreach ($this->getParentThemesList() as $theme) { + $config = $this->_config; + $config['theme'] = $theme->getCode(); + $translationFiles[] = $this->getThemeTranslationFileName($locale, $config); + } + + $translationFiles[] = $this->getThemeTranslationFileName($locale, $this->_config); + + return $translationFiles; + } + + /** * Retrieve translation file for theme * * @param string $locale * @return string + * + * @deprecated + * + * @see \Magento\Framework\Translate::getThemeTranslationFilesList */ protected function _getThemeTranslationFile($locale) { From 6a35e24869be3384e9f7d86bf6faed132d5b2bf6 Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Fri, 2 Nov 2018 14:16:30 +0200 Subject: [PATCH 628/812] =?UTF-8?q?magento/magento2#17833:=C2=A0=20Child?= =?UTF-8?q?=20theme=20does=20not=20inherit=20translations=20from=20parent?= =?UTF-8?q?=20theme=20-=20fix=20code=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/internal/Magento/Framework/Translate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index 3d5213cb2a40e..7994c22c14806 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -420,7 +420,7 @@ private function getParentThemesList(): array $themes = []; $parentTheme = $this->_viewDesign->getDesignTheme()->getParentTheme(); - while($parentTheme) { + while ($parentTheme) { $themes[] = $parentTheme; $parentTheme = $parentTheme->getParentTheme(); } From 51e240203aad14b5a0dcce42caf9041c92fc138d Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Fri, 2 Nov 2018 15:29:33 +0300 Subject: [PATCH 629/812] MAGETWO-91684: Issue with Newsletter subscriptions - Ensure that customer id is presented. --- .../Model/ResourceModel/Subscriber.php | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php b/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php index 5bd89c2798ce3..f9e9d57bf4b40 100644 --- a/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/ResourceModel/Subscriber.php @@ -132,28 +132,34 @@ public function loadByCustomerData(\Magento\Customer\Api\Data\CustomerInterface { $storeIds = $this->storeManager->getWebsite($customer->getWebsiteId())->getStoreIds(); - $select = $this->connection - ->select() - ->from($this->getMainTable()) - ->where('customer_id = ?', $customer->getId()) - ->where('store_id IN (?)', $storeIds); - - $result = $this->connection->fetchRow($select); - - if ($result) { - return $result; + if ($customer->getId()) { + $select = $this->connection + ->select() + ->from($this->getMainTable()) + ->where('customer_id = ?', $customer->getId()) + ->where('store_id IN (?)', $storeIds) + ->limit(1); + + $result = $this->connection->fetchRow($select); + + if ($result) { + return $result; + } } - $select = $this->connection - ->select() - ->from($this->getMainTable()) - ->where('subscriber_email = ?', $customer->getEmail()) - ->where('store_id IN (?)', $storeIds); + if ($customer->getEmail()) { + $select = $this->connection + ->select() + ->from($this->getMainTable()) + ->where('subscriber_email = ?', $customer->getEmail()) + ->where('store_id IN (?)', $storeIds) + ->limit(1); - $result = $this->connection->fetchRow($select); + $result = $this->connection->fetchRow($select); - if ($result) { - return $result; + if ($result) { + return $result; + } } return []; From 16731a0812d9a74fb55d4acc8e68af3716e1c728 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Fri, 2 Nov 2018 15:00:55 +0200 Subject: [PATCH 630/812] MAGETWO-96007: Customer address issue when creating or updating via API --- .../ResourceModel/CustomerRepositoryTest.php | 161 +++++++++++++----- 1 file changed, 114 insertions(+), 47 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php index 1af093bea06cc..15afc87405ffd 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php @@ -8,8 +8,24 @@ use Magento\Customer\Api\AccountManagementInterface; use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Api\Data\CustomerInterfaceFactory; +use Magento\Customer\Api\Data\AddressInterfaceFactory; +use Magento\Customer\Api\Data\RegionInterfaceFactory; +use Magento\Framework\Api\ExtensibleDataObjectConverter; +use Magento\Framework\Api\DataObjectHelper; +use Magento\Framework\Encryption\EncryptorInterface; +use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Customer\Model\CustomerRegistry; use Magento\Framework\Api\SortOrder; +use Magento\Framework\Config\CacheInterface; +use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Helper\Bootstrap; +use Magento\Customer\Api\Data\AddressInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Customer\Model\Customer; /** * Checks Customer insert, update, search with repository @@ -24,60 +40,65 @@ class CustomerRepositoryTest extends \PHPUnit\Framework\TestCase /** @var CustomerRepositoryInterface */ private $customerRepository; - /** @var \Magento\Framework\ObjectManagerInterface */ + /** @var ObjectManagerInterface */ private $objectManager; - /** @var \Magento\Customer\Api\Data\CustomerInterfaceFactory */ + /** @var CustomerInterfaceFactory */ private $customerFactory; - /** @var \Magento\Customer\Api\Data\AddressInterfaceFactory */ + /** @var AddressInterfaceFactory */ private $addressFactory; - /** @var \Magento\Customer\Api\Data\RegionInterfaceFactory */ + /** @var RegionInterfaceFactory */ private $regionFactory; - /** @var \Magento\Framework\Api\ExtensibleDataObjectConverter */ + /** @var ExtensibleDataObjectConverter */ private $converter; - /** @var \Magento\Framework\Api\DataObjectHelper */ + /** @var DataObjectHelper */ protected $dataObjectHelper; - /** @var \Magento\Framework\Encryption\EncryptorInterface */ + /** @var EncryptorInterface */ protected $encryptor; - /** @var \Magento\Customer\Model\CustomerRegistry */ + /** @var CustomerRegistry */ protected $customerRegistry; + /** + * @inheritdoc + */ protected function setUp() { $this->objectManager = Bootstrap::getObjectManager(); - $this->customerRepository = - $this->objectManager->create(\Magento\Customer\Api\CustomerRepositoryInterface::class); - $this->customerFactory = - $this->objectManager->create(\Magento\Customer\Api\Data\CustomerInterfaceFactory::class); - $this->addressFactory = $this->objectManager->create(\Magento\Customer\Api\Data\AddressInterfaceFactory::class); - $this->regionFactory = $this->objectManager->create(\Magento\Customer\Api\Data\RegionInterfaceFactory::class); - $this->accountManagement = - $this->objectManager->create(\Magento\Customer\Api\AccountManagementInterface::class); - $this->converter = $this->objectManager->create(\Magento\Framework\Api\ExtensibleDataObjectConverter::class); - $this->dataObjectHelper = $this->objectManager->create(\Magento\Framework\Api\DataObjectHelper::class); - $this->encryptor = $this->objectManager->create(\Magento\Framework\Encryption\EncryptorInterface::class); - $this->customerRegistry = $this->objectManager->create(\Magento\Customer\Model\CustomerRegistry::class); - - /** @var \Magento\Framework\Config\CacheInterface $cache */ - $cache = $this->objectManager->create(\Magento\Framework\Config\CacheInterface::class); + $this->customerRepository = $this->objectManager->create(CustomerRepositoryInterface::class); + $this->customerFactory = $this->objectManager->create(CustomerInterfaceFactory::class); + $this->addressFactory = $this->objectManager->create(AddressInterfaceFactory::class); + $this->regionFactory = $this->objectManager->create(RegionInterfaceFactory::class); + $this->accountManagement = $this->objectManager->create(AccountManagementInterface::class); + $this->converter = $this->objectManager->create(ExtensibleDataObjectConverter::class); + $this->dataObjectHelper = $this->objectManager->create(DataObjectHelper::class); + $this->encryptor = $this->objectManager->create(EncryptorInterface::class); + $this->customerRegistry = $this->objectManager->create(CustomerRegistry::class); + + /** @var CacheInterface $cache */ + $cache = $this->objectManager->create(CacheInterface::class); $cache->remove('extension_attributes_config'); } + /** + * @inheritdoc + */ protected function tearDown() { - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $objectManager = Bootstrap::getObjectManager(); /** @var \Magento\Customer\Model\CustomerRegistry $customerRegistry */ - $customerRegistry = $objectManager->get(\Magento\Customer\Model\CustomerRegistry::class); + $customerRegistry = $objectManager->get(CustomerRegistry::class); $customerRegistry->remove(1); } /** + * Check if first name update was successful + * * @magentoDbIsolation enabled */ public function testCreateCustomerNewThenUpdateFirstName() @@ -99,7 +120,7 @@ public function testCreateCustomerNewThenUpdateFirstName() $newCustomerFirstname = 'New First Name'; $updatedCustomer = $this->customerFactory->create(); $this->dataObjectHelper->mergeDataObjects( - \Magento\Customer\Api\Data\CustomerInterface::class, + CustomerInterface::class, $updatedCustomer, $customer ); @@ -112,6 +133,8 @@ public function testCreateCustomerNewThenUpdateFirstName() } /** + * Test create new customer + * * @magentoDbIsolation enabled */ public function testCreateNewCustomer() @@ -139,6 +162,8 @@ public function testCreateNewCustomer() } /** + * Test update customer + * * @dataProvider updateCustomerDataProvider * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php @@ -168,7 +193,7 @@ public function testUpdateCustomer($defaultBilling, $defaultShipping) $this->dataObjectHelper->populateWithArray( $customerDetails, $customerData, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $this->customerRepository->save($customerDetails, $newPasswordHash); $customerAfter = $this->customerRepository->getById($existingCustomerId); @@ -187,12 +212,12 @@ public function testUpdateCustomer($defaultBilling, $defaultShipping) $attributesBefore = $this->converter->toFlatArray( $customerBefore, [], - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $attributesAfter = $this->converter->toFlatArray( $customerAfter, [], - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); // ignore 'updated_at' unset($attributesBefore['updated_at']); @@ -215,6 +240,8 @@ public function testUpdateCustomer($defaultBilling, $defaultShipping) } /** + * Test update customer address + * * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php @@ -233,14 +260,14 @@ public function testUpdateCustomerAddress() $this->dataObjectHelper->populateWithArray( $newAddressDataObject, $newAddress, - \Magento\Customer\Api\Data\AddressInterface::class + AddressInterface::class ); $newAddressDataObject->setRegion($addresses[0]->getRegion()); $newCustomerEntity = $this->customerFactory->create(); $this->dataObjectHelper->populateWithArray( $newCustomerEntity, $customerDetails, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $newCustomerEntity->setId($customerId) ->setAddresses([$newAddressDataObject, $addresses[1]]); @@ -256,6 +283,8 @@ public function testUpdateCustomerAddress() } /** + * Test preserve all addresses after customer update + * * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php @@ -265,22 +294,37 @@ public function testUpdateCustomerPreserveAllAddresses() $customerId = 1; $customer = $this->customerRepository->getById($customerId); $customerDetails = $customer->__toArray(); + $defaultBilling = $customerDetails['default_billing']; + $defaultShipping = $customerDetails['default_shipping']; $newCustomerEntity = $this->customerFactory->create(); $this->dataObjectHelper->populateWithArray( $newCustomerEntity, $customerDetails, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $newCustomerEntity->setId($customer->getId()) ->setAddresses(null); $this->customerRepository->save($newCustomerEntity); $newCustomerDetails = $this->customerRepository->getById($customerId); + $newCustomerArray = $newCustomerDetails->__toArray(); //Verify that old addresses are still present $this->assertEquals(2, count($newCustomerDetails->getAddresses())); + $this->assertEquals( + $defaultBilling, + $newCustomerArray['default_billing'], + "Default billing invalid value" + ); + $this->assertEquals( + $defaultShipping, + $newCustomerArray['default_shipping'], + "Default shipping invalid value" + ); } /** + * Test update delete all addresses with empty arrays + * * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php @@ -294,18 +338,31 @@ public function testUpdateCustomerDeleteAllAddressesWithEmptyArray() $this->dataObjectHelper->populateWithArray( $newCustomerEntity, $customerDetails, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $newCustomerEntity->setId($customer->getId()) ->setAddresses([]); $this->customerRepository->save($newCustomerEntity); $newCustomerDetails = $this->customerRepository->getById($customerId); + $newCustomerArray = $newCustomerDetails->__toArray(); //Verify that old addresses are removed $this->assertEquals(0, count($newCustomerDetails->getAddresses())); + $this->assertEquals( + $newCustomerArray['default_billing'], + null, + "Default billing invalid value" + ); + $this->assertEquals( + $newCustomerArray['default_shipping'], + null, + "Default shipping invalid value" + ); } /** + * Test search customers + * * @param \Magento\Framework\Api\Filter[] $filters * @param \Magento\Framework\Api\Filter[] $filterGroup * @param array $expectedResult array of expected results indexed by ID @@ -317,9 +374,8 @@ public function testUpdateCustomerDeleteAllAddressesWithEmptyArray() */ public function testSearchCustomers($filters, $filterGroup, $expectedResult) { - /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchBuilder */ - $searchBuilder = Bootstrap::getObjectManager() - ->create(\Magento\Framework\Api\SearchCriteriaBuilder::class); + /** @var SearchCriteriaBuilder $searchBuilder */ + $searchBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); foreach ($filters as $filter) { $searchBuilder->addFilters([$filter]); } @@ -346,19 +402,19 @@ public function testSearchCustomers($filters, $filterGroup, $expectedResult) */ public function testSearchCustomersOrder() { - /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchBuilder */ + /** @var SearchCriteriaBuilder $searchBuilder */ $objectManager = Bootstrap::getObjectManager(); - $searchBuilder = $objectManager->create(\Magento\Framework\Api\SearchCriteriaBuilder::class); + $searchBuilder = $objectManager->create(SearchCriteriaBuilder::class); // Filter for 'firstname' like 'First' - $filterBuilder = $objectManager->create(\Magento\Framework\Api\FilterBuilder::class); + $filterBuilder = $objectManager->create(FilterBuilder::class); $firstnameFilter = $filterBuilder->setField('firstname') ->setConditionType('like') ->setValue('First%') ->create(); $searchBuilder->addFilters([$firstnameFilter]); // Search ascending order - $sortOrderBuilder = $objectManager->create(\Magento\Framework\Api\SortOrderBuilder::class); + $sortOrderBuilder = $objectManager->create(SortOrderBuilder::class); $sortOrder = $sortOrderBuilder ->setField('lastname') ->setDirection(SortOrder::SORT_ASC) @@ -383,6 +439,8 @@ public function testSearchCustomersOrder() } /** + * Test delete + * * @magentoAppArea adminhtml * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoAppIsolation enabled @@ -393,12 +451,14 @@ public function testDelete() $customer = $this->customerRepository->get($fixtureCustomerEmail); $this->customerRepository->delete($customer); /** Ensure that customer was deleted */ - $this->expectException(\Magento\Framework\Exception\NoSuchEntityException::class); + $this->expectException(NoSuchEntityException::class); $this->expectExceptionMessage('No such entity with email = customer@example.com, websiteId = 1'); $this->customerRepository->get($fixtureCustomerEmail); } /** + * Test delete by id + * * @magentoAppArea adminhtml * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoAppIsolation enabled @@ -409,7 +469,7 @@ public function testDeleteById() $fixtureCustomerId = 1; $this->customerRepository->deleteById($fixtureCustomerId); /** Ensure that customer was deleted */ - $this->expectException(\Magento\Framework\Exception\NoSuchEntityException::class); + $this->expectException(NoSuchEntityException::class); $this->expectExceptionMessage('No such entity with email = customer@example.com, websiteId = 1'); $this->customerRepository->get($fixtureCustomerEmail); } @@ -433,9 +493,14 @@ public function updateCustomerDataProvider() ]; } + /** + * Search customer data provider + * + * @return array + */ public function searchCustomersDataProvider() { - $builder = Bootstrap::getObjectManager()->create(\Magento\Framework\Api\FilterBuilder::class); + $builder = Bootstrap::getObjectManager()->create(FilterBuilder::class); return [ 'Customer with specific email' => [ [$builder->setField('email')->setValue('customer@search.example.com')->create()], @@ -485,9 +550,9 @@ protected function expectedDefaultShippingsInCustomerModelAttributes( $defaultShipping ) { /** - * @var \Magento\Customer\Model\Customer $customer + * @var Customer $customer */ - $customer = $this->objectManager->create(\Magento\Customer\Model\Customer::class); + $customer = $this->objectManager->create(Customer::class); /** @var \Magento\Customer\Model\Customer $customer */ $customer->load($customerId); $this->assertEquals( @@ -503,6 +568,8 @@ protected function expectedDefaultShippingsInCustomerModelAttributes( } /** + * Test update default shipping and default billing address + * * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDbIsolation enabled */ @@ -530,13 +597,13 @@ public function testUpdateDefaultShippingAndDefaultBillingTest() $this->assertEquals( $savedCustomer->getDefaultBilling(), $oldDefaultBilling, - 'Default billing shoud not be overridden' + 'Default billing should not be overridden' ); $this->assertEquals( $savedCustomer->getDefaultShipping(), $oldDefaultShipping, - 'Default shipping shoud not be overridden' + 'Default shipping should not be overridden' ); } } From bc8d3d5d0ead9779cb22d19201cd731719a79b0c Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Fri, 2 Nov 2018 15:01:25 +0200 Subject: [PATCH 631/812] magento/magento2#18256: Reset password throws error since 2.2.6. --- app/code/Magento/Customer/Model/AccountManagement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 9173307a7d270..8beecffd1c865 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -681,8 +681,8 @@ public function resetPassword($email, $resetToken, $newPassword) $customerSecure->setRpToken(null); $customerSecure->setRpTokenCreatedAt(null); $customerSecure->setPasswordHash($this->createPasswordHash($newPassword)); - $this->sessionManager->destroy(); $this->destroyCustomerSessions($customer->getId()); + $this->sessionManager->destroy(); $this->customerRepository->save($customer); return true; From c720d972108e6991f127f6f71e63485290dabe61 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Fri, 2 Nov 2018 15:05:08 +0200 Subject: [PATCH 632/812] magento/magento2:#18979 - API: Bundle Product Option Repository Delete method removes incorrect option --- app/code/Magento/Bundle/Model/OptionRepository.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Bundle/Model/OptionRepository.php b/app/code/Magento/Bundle/Model/OptionRepository.php index 59e658b08df28..a4d579a44174a 100644 --- a/app/code/Magento/Bundle/Model/OptionRepository.php +++ b/app/code/Magento/Bundle/Model/OptionRepository.php @@ -160,10 +160,9 @@ public function delete(\Magento\Bundle\Api\Data\OptionInterface $option) */ public function deleteById($sku, $optionId) { - $product = $this->getProduct($sku); - $optionCollection = $this->type->getOptionsCollection($product); - $optionCollection->setIdFilter($optionId); - $hasBeenDeleted = $this->delete($optionCollection->getFirstItem()); + /** @var \Magento\Bundle\Api\Data\OptionInterface $option */ + $option = $this->get($sku, $optionId); + $hasBeenDeleted = $this->delete($option); return $hasBeenDeleted; } From 21f52259c1f435a0fcb31ceb6f8a664fc2b7bf6c Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Fri, 2 Nov 2018 15:14:28 +0200 Subject: [PATCH 633/812] =?UTF-8?q?magento/magento2#17833:=C2=A0=20Child?= =?UTF-8?q?=20theme=20does=20not=20inherit=20translations=20from=20parent?= =?UTF-8?q?=20theme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/internal/Magento/Framework/Translate.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index 7994c22c14806..98ba6c0d718c3 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -400,14 +400,16 @@ protected function _getModuleTranslationFile($moduleName, $locale) * * @param string $locale * @param array $config - * @return string + * @return string|null */ - private function getThemeTranslationFileName(string $locale, array $config): string + private function getThemeTranslationFileName(string $locale, array $config): ?string { - return $this->_viewFileSystem->getLocaleFileName( + $fileName = $this->_viewFileSystem->getLocaleFileName( 'i18n' . '/' . $locale . '.csv', $config ); + + return $fileName ? $fileName : null; } /** From 936a22328f429b7e0dd631b6b20831ea91695cb6 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 2 Nov 2018 15:23:16 +0200 Subject: [PATCH 634/812] Added setting shipping method on cart test coverage concept --- .../Quote/SetShippingMethodOnCartTest.php | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php new file mode 100644 index 0000000000000..64c7cbf9fd42e --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php @@ -0,0 +1,120 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Quote; + +use Magento\Integration\Api\CustomerTokenServiceInterface; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface; +use Magento\Quote\Model\ResourceModel\Quote as QuoteResource; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQlAbstract; + +/** + * Test for setting shipping methods on cart + */ +class SetShippingMethodOnCartTest extends GraphQlAbstract +{ + /** + * @var CustomerTokenServiceInterface + */ + private $customerTokenService; + + /** + * @var QuoteResource + */ + private $quoteResource; + + /** + * @var Quote + */ + private $quote; + + /** + * @var QuoteIdToMaskedQuoteIdInterface + */ + private $quoteIdToMaskedId; + + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $this->quoteResource = $objectManager->create(QuoteResource::class); + $this->quote = $objectManager->create(Quote::class); + $this->quoteIdToMaskedId = $objectManager->create(QuoteIdToMaskedQuoteIdInterface::class); + $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetShippingOnCart() + { + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); + + $shippingAddress = $this->quote->getShippingAddress(); + $shippingAddressId = $shippingAddress->getId(); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $query = <<<QUERY +mutation { + setShippingMethodsOnCart(input: + { + cart_id: "$maskedQuoteId", + shipping_methods: [ + { + shipping_method_code: "flatrate" + shipping_carrier_code: "flatrate" + cart_address_id: $shippingAddressId + } + ]}) { + + cart { + cart_id, + addresses { + firstname + lastname + company + address_type + city + street + region { + code + label + } + postcode + country { + code + label + } + + selected_shipping_method { + code + label + } + } + } + } +} + +QUERY; + + $customerToken = $this->customerTokenService->createCustomerAccessToken('customer@example.com', 'password'); + $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; + $response = $this->graphQlQuery($query, [], '', $headerMap); + + self::assertArrayHasKey('setShippingMethodsOnCart', $response); + self::assertArrayHasKey('cart', $response['setShippingMethodsOnCart']); + self::assertEquals($maskedQuoteId, $response['setShippingMethodsOnCart']['cart']['cart_id']); + + // TODO: check shipping method code and description + } + + // TODO: cover all other cases +} From 76d478fa2c70c5c6ac07c7ef781ce46aeadffd06 Mon Sep 17 00:00:00 2001 From: Oleksii Gorbulin <a.gorbulin@ism-ukraine.com> Date: Fri, 2 Nov 2018 15:27:42 +0200 Subject: [PATCH 635/812] 18901-Forgot-password-form-should-not-available-while-customer-is-logged-in magento/magento2#18901: Forgot password form should not available while customer is logged in --- .../Customer/Controller/Account/ForgotPassword.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Controller/Account/ForgotPassword.php b/app/code/Magento/Customer/Controller/Account/ForgotPassword.php index 8b5d0612050c3..b94f1993053d4 100644 --- a/app/code/Magento/Customer/Controller/Account/ForgotPassword.php +++ b/app/code/Magento/Customer/Controller/Account/ForgotPassword.php @@ -41,10 +41,17 @@ public function __construct( /** * Forgot customer password page * - * @return \Magento\Framework\View\Result\Page + * @return \Magento\Framework\Controller\Result\Redirect|\Magento\Framework\View\Result\Page */ public function execute() { + if ($this->session->isLoggedIn()) { + /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */ + $resultRedirect = $this->resultRedirectFactory->create(); + $resultRedirect->setPath('*/*/'); + return $resultRedirect; + } + /** @var \Magento\Framework\View\Result\Page $resultPage */ $resultPage = $this->resultPageFactory->create(); $resultPage->getLayout()->getBlock('forgotPassword')->setEmailValue($this->session->getForgottenEmail()); From a30654fb794e4517cdfec07ac431824e2243dec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Szyma=C5=84ski?= <bartlomiej.szymanski@bold.net.pl> Date: Fri, 2 Nov 2018 14:29:17 +0100 Subject: [PATCH 636/812] Replace GraphQlInputException on \LogicException --- .../Model/LayerFilterItemTypeResolverComposite.php | 4 +--- .../Model/ProductLinkTypeResolverComposite.php | 4 +--- app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php | 7 +------ 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php b/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php index 20e5590117556..e04b5d1bf67ff 100644 --- a/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php @@ -43,9 +43,7 @@ public function resolveType(array $data) : string } } if (empty($resolvedType)) { - throw new GraphQlInputException( - __('Concrete type for %1 not implemented', ['ProductLinksInterface']) - ); + throw new \LogicException('Cannot resolve layered filter type'); } } } diff --git a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php index 937e3921758dc..5f6d1a65519f8 100644 --- a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php @@ -50,9 +50,7 @@ public function resolveType(array $data) : string } if (!$resolvedType) { - throw new GraphQlInputException( - __('Concrete type for %1 not implemented', ['ProductLinksInterface']) - ); + throw new \LogicException('Cannot resolve type'); } } } diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php index cbea3a86bbddd..b1d7aae5df101 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php @@ -71,12 +71,7 @@ public function getType(string $attributeCode, string $entityType) : string try { $type = $this->typeProcessor->translateTypeName($type); } catch (\InvalidArgumentException $exception) { - throw new GraphQlInputException( - __('Type %1 has no internal representation declared.', [$type]), - null, - 0, - false - ); + throw new \LogicException('Cannot resolve EAV type'); } } else { $type = $type === 'double' ? 'float' : $type; From 12e0c534e70632deff7e177fa716b79dfbbf83ba Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 2 Nov 2018 16:55:05 +0300 Subject: [PATCH 637/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fix static test --- app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php index a2cbc5087cd12..c530ba4785ad9 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php @@ -146,10 +146,10 @@ class Toolbar extends \Magento\Framework\View\Element\Template * @param \Magento\Framework\Url\EncoderInterface $urlEncoder * @param ProductList $productListHelper * @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper + * @param array $data * @param ToolbarMemorizer|null $toolbarMemorizer * @param \Magento\Framework\App\Http\Context|null $httpContext * @param \Magento\Framework\Data\Form\FormKey|null $formKey - * @param array $data * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ From 144ea18392229aef98c5a21165fba106bd97840d Mon Sep 17 00:00:00 2001 From: Lars Roettig <l.roettig@techdivision.com> Date: Fri, 2 Nov 2018 15:34:08 +0100 Subject: [PATCH 638/812] CodeReviewChange --- .../Magento/Store/Model/Config/Importer/Processor/Create.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php index 3142955ac5988..9d1a7a38ede68 100644 --- a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php +++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php @@ -177,7 +177,10 @@ private function createGroups(array $items, array $data) ); $group = $this->groupFactory->create(); - $group->setRootCategoryId(0); + if (!isset($groupData['root_categry_id'])) { + $groupData['root_categry_id'] = 0; + } + $group->setData($groupData); $group->getResource()->save($group); From 9498e05885b865a6c4589221ebf20491360d41a7 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Fri, 2 Nov 2018 09:44:30 -0500 Subject: [PATCH 639/812] MAGETWO-95659: Fix and Unskip MTF OnePageCheckoutOfflinePaymentMethodsTest --- .../Test/Constraint/AssertCartIsEmpty.php | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php index c2839651b582f..22a6136737089 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php @@ -6,7 +6,6 @@ namespace Magento\Checkout\Test\Constraint; -use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Page\CheckoutCart; use Magento\Mtf\Client\BrowserInterface; use Magento\Mtf\Constraint\AbstractConstraint; @@ -42,10 +41,12 @@ public function processAssert(CheckoutCart $checkoutCart, BrowserInterface $brow ); $cartEmptyBlock->clickLinkToMainPage(); - \PHPUnit\Framework\Assert::assertEquals( + $this->assertUrlEqual( $_ENV['app_frontend_url'], $browser->getUrl(), - 'Wrong link to main page on empty cart page.' + true, + 'Wrong link to main page on empty cart page: expected - ' . $_ENV['app_frontend_url'] + . ', actural - ' . $browser->getUrl() ); } @@ -58,4 +59,27 @@ public function toString() { return 'Shopping Cart is empty.'; } + + /** + * Asserts that two urls are equal + * + * @param string $url1 + * @param string $url2 + * @param bool $ignoreScheme + * @param string $message + * @return void + */ + private function assertUrlEqual($expectedUrl, $actualUrl, $ignoreScheme = false, $message = '') + { + $urlArray1 = parse_url($expectedUrl); + $urlArray2 = parse_url($actualUrl); + if ($ignoreScheme) { + unset($urlArray1['scheme']); + unset($urlArray2['scheme']); + } + \PHPUnit\Framework\Assert::assertTrue( + $urlArray1 === $urlArray2, + $message + ); + } } From 0a6c0b5a792dbba00295bea9b9b902c7b9598205 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Fri, 2 Nov 2018 17:15:09 +0200 Subject: [PATCH 640/812] graphQl: removed multishipping implementation, fixed namespaces --- .../SetShippingAddressOnCart.php} | 19 ++- .../Resolver/SetShippingAddressesOnCart.php | 101 +++++++++++++ .../MultiShipping.php | 76 ---------- .../MultiShipping/ShippingItemsMapper.php | 43 ------ .../SetShippingAddressesOnCart.php | 133 ------------------ .../Magento/QuoteGraphQl/etc/schema.graphqls | 3 +- 6 files changed, 117 insertions(+), 258 deletions(-) rename app/code/Magento/QuoteGraphQl/Model/{Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php => Cart/SetShippingAddressOnCart.php} (85%) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php delete mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php delete mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php delete mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php similarity index 85% rename from app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php rename to app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php index feeb333683f76..43e58bb807672 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/SingleShipping.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart; +namespace Magento\QuoteGraphQl\Model\Cart; use Magento\Authorization\Model\UserContextInterface; use Magento\Customer\Api\Data\AddressInterface; @@ -16,7 +16,12 @@ use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\Customer\Api\AddressRepositoryInterface; -class SingleShipping +/** + * Class SetShippingAddressOnCart + * + * Set shipping address for a specified shopping cart + */ +class SetShippingAddressOnCart { /** * @var ShippingAddressManagementInterface @@ -51,11 +56,17 @@ public function __construct( /** * @param ContextInterface $context * @param int $cartId - * @param array $shippingAddress + * @param array $shippingAddresses * @return void */ - public function setAddress(ContextInterface $context, int $cartId, array $shippingAddress): void + public function setAddresses(ContextInterface $context, int $cartId, array $shippingAddresses): void { + if (count($shippingAddresses) > 1) { + throw new GraphQlInputException( + __('Multiple address does not allowed here!') + ); + } + $shippingAddress = current($shippingAddresses); $customerAddressId = $shippingAddress['customer_address_id'] ?? null; $addressInput = $shippingAddress['address'] ?? null; diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php new file mode 100644 index 0000000000000..fcb4255a75eb7 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\Stdlib\ArrayManager; +use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; +use Magento\Quote\Model\ShippingAddressManagementInterface; +use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; +use Magento\QuoteGraphQl\Model\Cart\SetShippingAddressOnCart; + +/** + * Class SetShippingAddressesOnCart + * + * Mutation resolver for setting shipping addresses for shopping cart + */ +class SetShippingAddressesOnCart implements ResolverInterface +{ + /** + * @var MaskedQuoteIdToQuoteIdInterface + */ + private $maskedQuoteIdToQuoteId; + + /** + * @var SetShippingAddressOnCart + */ + private $setShippingAddressOnCart; + + /** + * @var ShippingAddressManagementInterface + */ + private $shippingAddressManagement; + + /** + * @var GetCartForUser + */ + private $getCartForUser; + + /** + * @var ArrayManager + */ + private $arrayManager; + + /** + * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId + * @param SetShippingAddressOnCart $setShippingAddressOnCart + * @param ShippingAddressManagementInterface $shippingAddressManagement + * @param GetCartForUser $getCartForUser + * @param ArrayManager $arrayManager + */ + public function __construct( + MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, + SetShippingAddressOnCart $setShippingAddressOnCart, + ShippingAddressManagementInterface $shippingAddressManagement, + GetCartForUser $getCartForUser, + ArrayManager $arrayManager + ) { + $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; + $this->setShippingAddressOnCart = $setShippingAddressOnCart; + $this->shippingAddressManagement = $shippingAddressManagement; + $this->getCartForUser = $getCartForUser; + $this->arrayManager = $arrayManager; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + $shippingAddresses = $this->arrayManager->get('input/shipping_addresses', $args); + $maskedCartId = $this->arrayManager->get('input/cart_id', $args); + + if (!$maskedCartId) { + throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); + } + if (!$shippingAddresses) { + throw new GraphQlInputException(__('Required parameter "shipping_addresses" is missing')); + } + + $maskedCartId = $args['input']['cart_id']; + $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId()); + $cartId = (int)$cart->getEntityId(); + + $this->setShippingAddressOnCart->setAddresses($context, $cartId, $shippingAddresses); + + return [ + 'cart' => [ + 'cart_id' => $maskedCartId, + 'model' => $cart + ] + ]; + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php deleted file mode 100644 index 318fd9361af5a..0000000000000 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping.php +++ /dev/null @@ -1,76 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart; - -use Magento\Authorization\Model\UserContextInterface; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Multishipping\Model\Checkout\Type\Multishipping as MultishippingModel; -use Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\MultiShipping\ShippingItemsMapper; - -class MultiShipping -{ - /** - * @var MultishippingModel - */ - private $multishippingModel; - - /** - * @var ShippingItemsMapper - */ - private $shippingItemsInformationMapper; - - /** - * @param MultishippingModel $multishippingModel - * @param ShippingItemsMapper $shippingItemsInformationMapper - */ - public function __construct( - MultishippingModel $multishippingModel, - ShippingItemsMapper $shippingItemsInformationMapper - ) { - $this->multishippingModel = $multishippingModel; - $this->shippingItemsInformationMapper = $shippingItemsInformationMapper; - } - - /** - * @param ContextInterface $context - * @param int $cartId - * @param array $shippingAddresses - */ - public function setAddresses(ContextInterface $context, int $cartId, array $shippingAddresses): void - { - if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { - throw new GraphQlAuthorizationException( - __( - 'Multishipping allowed only for authorized customers' - ) - ); - } - - $shippingItemsInformation = []; - foreach ($shippingAddresses as $shippingAddress) { - $customerAddressId = $shippingAddress['customer_address_id'] ?? null; - $cartItems = $shippingAddress['cart_items'] ?? null; - if (!$customerAddressId) { - throw new GraphQlInputException(__('Parameter "customer_address_id" is required for multishipping')); - } - if (!$cartItems) { - throw new GraphQlInputException(__('Parameter "cart_items" is required for multishipping')); - } - - $shippingItemsInformation = array_merge( - $shippingItemsInformation, - $this->shippingItemsInformationMapper->map($shippingAddress) - ); - } - - //TODO: multishipping model works with session. Do we need to avoid it? - $this->multishippingModel->setShippingItemsInformation($shippingItemsInformation); - } -} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php deleted file mode 100644 index ad5207814db7c..0000000000000 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressOnCart/MultiShipping/ShippingItemsMapper.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\MultiShipping; - -/** - * Shipping address to shipping items mapper - */ -class ShippingItemsMapper -{ - - /** - * Converts shipping address input array into shipping items information array - * Array structure: - * array( - * $cartItemId => array( - * 'qty' => $qty, - * 'address' => $customerAddressId - * ) - * ) - * - * @param array $shippingAddress - * @return array - */ - public function map(array $shippingAddress): array - { - $shippingItemsInformation = []; - foreach ($shippingAddress['cart_items'] as $cartItem) { - $shippingItemsInformation[] = [ - $cartItem['cart_item_id'] => [ - 'qty' => $cartItem['quantity'], - 'address' => $shippingAddress['customer_address_id'] - ] - ]; - } - - return $shippingItemsInformation; - } -} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php deleted file mode 100644 index 7ffa6c4950b3d..0000000000000 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/SetShippingAddressesOnCart.php +++ /dev/null @@ -1,133 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\QuoteGraphQl\Model\Resolver\ShippingAddress; - -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; -use Magento\Quote\Model\ShippingAddressManagementInterface; -use Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\MultiShipping; -use Magento\QuoteGraphQl\Model\Resolver\ShippingAddress\SetShippingAddressOnCart\SingleShipping; - -/** - * @inheritdoc - */ -class SetShippingAddressesOnCart implements ResolverInterface -{ - /** - * @var MaskedQuoteIdToQuoteIdInterface - */ - private $maskedQuoteIdToQuoteId; - - /** - * @var MultiShipping - */ - private $multiShipping; - - /** - * @var SingleShipping - */ - private $singleShipping; - - /** - * @var ShippingAddressManagementInterface - */ - private $shippingAddressManagement; - - /** - * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId - * @param MultiShipping $multiShipping - * @param SingleShipping $singleShipping - * @param ShippingAddressManagementInterface $shippingAddressManagement - */ - public function __construct( - MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, - MultiShipping $multiShipping, - SingleShipping $singleShipping, - ShippingAddressManagementInterface $shippingAddressManagement - ) { - $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->multiShipping = $multiShipping; - $this->singleShipping = $singleShipping; - $this->shippingAddressManagement = $shippingAddressManagement; - } - - /** - * @inheritdoc - */ - public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) - { - if (!isset($args['input']['cart_id'])) { - throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); - } - if (!isset($args['input']['shipping_addresses'])) { - throw new GraphQlInputException(__('Required parameter "shipping_addresses" is missing')); - } - - $shippingAddressesInput = $args['input']['shipping_addresses']; - $maskedCartId = $args['input']['cart_id']; - $cartId = $this->maskedQuoteIdToQuoteId->execute($maskedCartId); - - if (count($shippingAddressesInput) === 1) { - $this->singleShipping->setAddress($context, $cartId, current($shippingAddressesInput)); - } else { - $this->multiShipping->setAddresses($context, $cartId, $shippingAddressesInput); - } - - //TODO: implement Cart object in the separate resolver - $shippingAddress = $this->shippingAddressManagement->get($cartId); - return [ - 'cart' => [ - 'applied_coupon' => [ - 'code' => '' - ], - 'addresses' => [[ - 'firstname' => $shippingAddress->getFirstname(), - 'lastname' => $shippingAddress->getLastname(), - 'company' => $shippingAddress->getCompany(), - 'street' => $shippingAddress->getStreet(), - 'city' => $shippingAddress->getCity(), - 'region' => [ - 'code' => $shippingAddress->getRegionCode(), - 'label' => $shippingAddress->getRegion() - ], - 'country' => [ - 'code' => $shippingAddress->getCountryId(), - 'label' => '' - ], - 'postcode' => $shippingAddress->getPostcode(), - 'telephone' => $shippingAddress->getTelephone(), - 'address_type' => 'SHIPPING', - 'selected_shipping_method' => [ - 'code' => 'test', - 'label' => 'test', - 'free_shipping' => 'test', - 'error_message' => 'test' - ], - 'available_shipping_methods' => [[ - 'code' => 'test', - 'label' => 'test', - 'free_shipping' => 'test', - 'error_message' => 'test' - ]], - 'items_weight' => [0], - 'customer_notes' => $shippingAddress->getLastname(), - 'cart_items' => [[ - 'cart_item_id' => '', - 'quantity' => 0 - ]], - 'applied_coupon' => [ - 'code' => '' - ] - ]] - ] - ]; - } -} diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 7312c15e06580..017b1f8119829 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -9,11 +9,10 @@ type Mutation { createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") - setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ShippingAddress\\SetShippingAddressesOnCart") + setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingAddressesOnCart") createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveCouponFromCart") - setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingMethodsOnCart") addSimpleProductsToCart(input: AddSimpleProductsToCartInput): AddSimpleProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddSimpleProductsToCart") From e18df69004ef25f53ed927e953cc5fce0191bf84 Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Fri, 2 Nov 2018 17:26:27 +0200 Subject: [PATCH 641/812] magento/magento2#14007: "Use in Layered Navigation: Filterable (no results)" not working for `Price` attribute. - adjust comment for "Use in Layered Navigation: Filterable (no results)" property to make it more understandable --- .../Tab/Front/ProductAttributeFormBuildFrontTabObserver.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php b/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php index 1bb601e3a4ebd..ce618f97883b0 100644 --- a/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php +++ b/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php @@ -60,7 +60,11 @@ public function execute(\Magento\Framework\Event\Observer $observer) 'name' => 'is_filterable', 'label' => __("Use in Layered Navigation"), 'title' => __('Can be used only with catalog input type Yes/No, Dropdown, Multiple Select and Price'), - 'note' => __('Can be used only with catalog input type Yes/No, Dropdown, Multiple Select and Price.'), + 'note' => __( + 'Can be used only with catalog input type Yes/No, Dropdown, Multiple Select and Price. + <br>Price is not compatible with <b>\'Filterable (no results)\'</b> option - + it will make no affect on Price filter.' + ), 'values' => [ ['value' => '0', 'label' => __('No')], ['value' => '1', 'label' => __('Filterable (with results)')], From e19d70e3fd43184eeeb009129bf0a564fae002ea Mon Sep 17 00:00:00 2001 From: "al.kravchuk" <al.kravchuk@ism-ukraine.com> Date: Fri, 2 Nov 2018 16:42:45 +0200 Subject: [PATCH 642/812] magento/magento2#18323: Order confirmation email for guest checkout does not include download links. - move save downloadable items from 'save_commit_after' to 'save_after' event. --- app/code/Magento/Downloadable/etc/events.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Downloadable/etc/events.xml b/app/code/Magento/Downloadable/etc/events.xml index e4f03ff238d4a..5a985fc33802e 100644 --- a/app/code/Magento/Downloadable/etc/events.xml +++ b/app/code/Magento/Downloadable/etc/events.xml @@ -6,10 +6,10 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> - <event name="sales_order_item_save_commit_after"> + <event name="sales_order_item_save_after"> <observer name="downloadable_observer" instance="Magento\Downloadable\Observer\SaveDownloadableOrderItemObserver" /> </event> - <event name="sales_order_save_commit_after"> + <event name="sales_order_save_after"> <observer name="downloadable_observer" instance="Magento\Downloadable\Observer\SetLinkStatusObserver" /> </event> <event name="sales_model_service_quote_submit_success"> From c8941f1d13a82e0c3d1c65dbf262a5e295933f3f Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Fri, 2 Nov 2018 18:47:41 +0300 Subject: [PATCH 643/812] MAGETWO-61478: Number of Products displayed per page not retained when visiting a different category - Fix statics. --- app/code/Magento/Catalog/Controller/Category/View.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Category/View.php b/app/code/Magento/Catalog/Controller/Category/View.php index 43f25c58a70dd..2088bb5ea77cd 100644 --- a/app/code/Magento/Catalog/Controller/Category/View.php +++ b/app/code/Magento/Catalog/Controller/Category/View.php @@ -208,7 +208,7 @@ public function execute() if ($layoutUpdates && is_array($layoutUpdates)) { foreach ($layoutUpdates as $layoutUpdate) { $page->addUpdate($layoutUpdate); - $page->addPageLayoutHandles(['layout_update' => md5($layoutUpdate)], null, false); + $page->addPageLayoutHandles(['layout_update' => sha1($layoutUpdate)], null, false); } } From 70743fa4f5e5a6c6ba416d33cfb9d36faaaa47c2 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 2 Nov 2018 18:14:21 +0200 Subject: [PATCH 644/812] #10048 - WYSIWYG unable to set default value in ui component --- app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js index 6507da5e1a933..29a0cc0f0c295 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js @@ -20,7 +20,6 @@ define([ return Abstract.extend({ defaults: { elementSelector: 'textarea', - value: '', $wysiwygEditorButton: '', links: { value: '${ $.provider }:${ $.dataScope }' From 4ec4c0e1f390c987b6db7efd799cb0da74df1770 Mon Sep 17 00:00:00 2001 From: Joan He <johe@adobe.com> Date: Fri, 2 Nov 2018 11:54:18 -0500 Subject: [PATCH 645/812] MAGETWO-95660: Fix and Unskip MTF OnePageCheckoutTest --- .../Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml index 5c05d4a840009..0edd8f4183f30 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml @@ -7,7 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Checkout\Test\TestCase\OnePageCheckoutTest" summary="OnePageCheckout within Offline Payment Methods" ticketId="MAGETWO-27485"> - <variation name="OnePageCheckoutUsingSingInLink" summary="Login during checkout using 'Sign In' link" ticketId="MAGETWO-42547"> + <variation name="OnePageCheckoutUsingSignInLink" summary="Login during checkout using 'Sign In' link" ticketId="MAGETWO-42547"> <data name="tag" xsi:type="string">severity:S1</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="customer/dataset" xsi:type="string">customer_UK_US_addresses</data> @@ -49,10 +49,6 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderAddresses" /> - <!-- MAGETWO-94169 --> - <data name="tag" xsi:type="string">stable:no</data> - <data name="issue" xsi:type="string">MAGETWO-94169: [MTF] - OnePageCheckoutUsingNonDefaultAddress_0 fails on 2.3-develop</data> - <!-- MAGETWO-94169 --> </variation> <variation name="OnePageCheckoutUsingNewAddress" summary="Checkout as Customer using New address" ticketId="MAGETWO-42601"> <data name="tag" xsi:type="string">severity:S1</data> From 90cf2e0da44ba17b8d21307e062be80391d402e5 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Fri, 2 Nov 2018 17:09:40 +0000 Subject: [PATCH 646/812] Removed unnecessary empty line --- lib/internal/Magento/Framework/Translate.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index 98ba6c0d718c3..ff1bf99162a8a 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -454,7 +454,6 @@ private function getThemeTranslationFilesList($locale): array return $translationFiles; } - /** * Retrieve translation file for theme * From d1e749aa37878c3c3be3a15f216745978d95a804 Mon Sep 17 00:00:00 2001 From: Arnoud Beekman <arnoudhgz@gmail.com> Date: Fri, 2 Nov 2018 22:34:49 +0100 Subject: [PATCH 647/812] Add/update newsletter messages in translation file --- app/code/Magento/Newsletter/i18n/en_US.csv | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Newsletter/i18n/en_US.csv b/app/code/Magento/Newsletter/i18n/en_US.csv index c49fdc80da810..388b583f990b1 100644 --- a/app/code/Magento/Newsletter/i18n/en_US.csv +++ b/app/code/Magento/Newsletter/i18n/en_US.csv @@ -67,8 +67,8 @@ Subscribers,Subscribers "Something went wrong while saving this template.","Something went wrong while saving this template." "Newsletter Subscription","Newsletter Subscription" "Something went wrong while saving your subscription.","Something went wrong while saving your subscription." -"We saved the subscription.","We saved the subscription." -"We removed the subscription.","We removed the subscription." +"We have saved your subscription.","We have saved your subscription." +"We have removed your newsletter subscription.","We have removed your newsletter subscription." "Your subscription has been confirmed.","Your subscription has been confirmed." "This is an invalid subscription confirmation code.","This is an invalid subscription confirmation code." "This is an invalid subscription ID.","This is an invalid subscription ID." @@ -76,7 +76,7 @@ Subscribers,Subscribers "Sorry, but the administrator denied subscription for guests. Please <a href=""%1"">register</a>.","Sorry, but the administrator denied subscription for guests. Please <a href=""%1"">register</a>." "Please enter a valid email address.","Please enter a valid email address." "This email address is already subscribed.","This email address is already subscribed." -"The confirmation request has been sent.","The confirmation request has been sent." +"A confirmation request has been sent.","A confirmation request has been sent." "Thank you for your subscription.","Thank you for your subscription." "There was a problem with the subscription: %1","There was a problem with the subscription: %1" "Something went wrong with the subscription.","Something went wrong with the subscription." @@ -151,3 +151,4 @@ Unconfirmed,Unconfirmed Store,Store "Store View","Store View" "Newsletter Subscriptions","Newsletter Subscriptions" +"We have updated your subscription.","We have updated your subscription." From 7682fa08ca31f36400ec29778f014389131e707a Mon Sep 17 00:00:00 2001 From: Daniel Ruf <daniel@daniel-ruf.de> Date: Sat, 3 Nov 2018 10:56:00 +0100 Subject: [PATCH 648/812] chore: move count variable to loop variables --- app/code/Magento/Paypal/Model/Report/Settlement.php | 3 +-- .../Test/TestCase/Product/AddCompareProductsTest.php | 3 +-- .../Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php | 3 +-- .../Test/TestStep/FillShippingInformationStep.php | 3 +-- .../Test/Constraint/AssertProductsQtyAfterOrderCancel.php | 3 +-- .../Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php | 3 +-- .../Magento/Sniffs/Translation/ConstantUsageSniffTest.php | 3 +-- .../testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php | 5 ++--- .../Framework/App/Test/Unit/Language/DictionaryTest.php | 3 +-- lib/internal/Magento/Framework/Archive.php | 7 +++---- lib/internal/Magento/Framework/Cache/Backend/Memcached.php | 3 +-- lib/internal/Magento/Framework/Filter/Template.php | 3 +-- lib/internal/Magento/Framework/System/Ftp.php | 3 +-- .../src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php | 6 ++---- setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php | 6 ++---- 15 files changed, 20 insertions(+), 37 deletions(-) diff --git a/app/code/Magento/Paypal/Model/Report/Settlement.php b/app/code/Magento/Paypal/Model/Report/Settlement.php index b2ab1627b24d4..5dc51518f0b11 100644 --- a/app/code/Magento/Paypal/Model/Report/Settlement.php +++ b/app/code/Magento/Paypal/Model/Report/Settlement.php @@ -409,8 +409,7 @@ public function parseCsv($localCsv, $format = 'new') private function getBodyItems(array $line, array $sectionColumns, array $rowMap) { $bodyItem = []; - $lineCount = count($line); - for ($i = 1, $count = $lineCount; $i < $count; $i++) { + for ($i = 1, $count = count($line); $i < $count; $i++) { if (isset($rowMap[$sectionColumns[$i]])) { if (in_array($rowMap[$sectionColumns[$i]], $this->dateTimeColumns)) { $line[$i] = $this->formatDateTimeColumns($line[$i]); diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php index da0aa49d9697b..c40387aba4603 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php @@ -76,8 +76,7 @@ public function tearDown() { $this->cmsIndex->open(); $this->cmsIndex->getLinksBlock()->openLink("Compare Products"); - $productsCount = count($this->products); - for ($i = 1; $i <= $productsCount; $i++) { + for ($i = 1, $count = count($this->products); $i <= $count; $i++) { $this->catalogProductCompare->getCompareProductsBlock()->removeProduct(); } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php index 381c18d3ee686..7365195d0cd44 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/ShoppingCartPerCustomerTest.php @@ -95,8 +95,7 @@ public function test( $customers = []; $cartFixtures = []; - $checkoutDataCount = count($checkoutData); - for ($i = 0; $i < $checkoutDataCount; $i++) { + for ($i = 0, $count = count($checkoutData); $i < $count; $i++) { $customers[$i] = $this->fixtureFactory->createByCode('customer', ['dataset' => $customerDataset]); $customers[$i]->persist(); diff --git a/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php b/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php index 248dfc8e16dc9..73b2f762057b0 100644 --- a/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php +++ b/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php @@ -58,8 +58,7 @@ public function __construct( public function run() { $shippingMethods = []; - $addressCount = $this->customer->getAddress(); - for ($i = 0; $i < $addressCount; $i++) { + for ($i = 0, $count = $this->customer->getAddress(); $i < $count; $i++) { $shippingMethods[] = $this->shippingMethod; } $this->shippingInformation->getShippingBlock()->selectShippingMethod($shippingMethods); diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php index 7d229bc358995..24027cacd9e4a 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductsQtyAfterOrderCancel.php @@ -52,8 +52,7 @@ public function processAssert( AssertProductForm $assertProductForm, AssertConfigurableProductForm $assertConfigurableProductForm ) { - $productsCount = count($order->getEntityId()['products']); - for ($i = 0; $i < $productsCount; $i++) { + for ($i = 0, $count = count($order->getEntityId()['products']); $i < $count; $i++) { $product = $order->getEntityId()['products'][$i]; $productData = $product->getData(); if ($product instanceof BundleProduct) { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php index 87ba4d7c2808c..e3a948d6c63de 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/AlgorithmBaseTest.php @@ -112,8 +112,7 @@ public function testPricesSegmentation($categoryId, array $entityIds, array $int $items = $model->calculateSeparators($interval); $this->assertEquals(array_keys($intervalItems), array_keys($items)); - $intervalItemsCount = count($intervalItems); - for ($i = 0; $i < $intervalItemsCount; ++$i) { + for ($i = 0, $count = count($intervalItems); $i < $count; ++$i) { $this->assertInternalType('array', $items[$i]); $this->assertEquals($intervalItems[$i]['from'], $items[$i]['from']); $this->assertEquals($intervalItems[$i]['to'], $items[$i]['to']); diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php index 06a8a0accc732..65512653ce3fa 100644 --- a/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/Sniffs/Translation/ConstantUsageSniffTest.php @@ -67,8 +67,7 @@ private function tokenizeString($fileContent) $lineNumber = 1; $tokens = token_get_all($fileContent); $snifferTokens = []; - $tokensCount = count($tokens); - for ($i = 0; $i < $tokensCount; $i++) { + for ($i = 0, $count = count($tokens); $i < $count; $i++) { $content = is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i]; $snifferTokens[$i]['line'] = $lineNumber; $snifferTokens[$i]['content'] = $content; diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php index 0560158a82668..fe15c06bdea4a 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/ObsoleteCodeTest.php @@ -501,9 +501,8 @@ private function _checkConstantWithClasspath($constant, $class, $replacement, $c { $classPathParts = explode('\\', $class); $classPartialPath = ''; - $classPathPartsCount = count($classPathParts); - for ($i = $classPathPartsCount - 1; $i >= 0; $i--) { - if ($i === ($classPathPartsCount - 1)) { + for ($count = count($classPathParts), $i = $count - 1; $i >= 0; $i--) { + if ($i === ($count - 1)) { $classPartialPath = $classPathParts[$i] . $classPartialPath; } else { $classPartialPath = $classPathParts[$i] . '\\' . $classPartialPath; diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php index 67518a6c7d142..748337443d7a8 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Language/DictionaryTest.php @@ -52,8 +52,7 @@ public function testDictionaryGetter() } $file = $this->getMockForAbstractClass(\Magento\Framework\Filesystem\File\ReadInterface::class); - $dataCount = count($data); - for ($i = 0; $i < $dataCount; $i++) { + for ($i = 0, $count = count($data); $i < $count; $i++) { $file->expects($this->at($i))->method('readCsv')->will($this->returnValue($data[$i])); } $file->expects($this->at($i))->method('readCsv')->will($this->returnValue(false)); diff --git a/lib/internal/Magento/Framework/Archive.php b/lib/internal/Magento/Framework/Archive.php index 7c4b6984b3fc4..3b706f8e97d07 100644 --- a/lib/internal/Magento/Framework/Archive.php +++ b/lib/internal/Magento/Framework/Archive.php @@ -96,15 +96,14 @@ public function pack($source, $destination = 'packed.tgz', $skipRoot = false) { $archivers = $this->_getArchivers($destination); $interimSource = ''; - $archiversCount = count($archivers); - for ($i = 0; $i < $archiversCount; $i++) { - if ($i == $archiversCount - 1) { + for ($i = 0, $count = count($archivers); $i < $count; $i++) { + if ($i == $count - 1) { $packed = $destination; } else { $packed = dirname($destination) . '/~tmp-' . microtime(true) . $archivers[$i] . '.' . $archivers[$i]; } $source = $this->_getArchiver($archivers[$i])->pack($source, $packed, $skipRoot); - if ($interimSource && $i < $archiversCount) { + if ($interimSource && $i < $count) { unlink($interimSource); } $interimSource = $source; diff --git a/lib/internal/Magento/Framework/Cache/Backend/Memcached.php b/lib/internal/Magento/Framework/Cache/Backend/Memcached.php index c793714f69153..ff9413aa90fea 100644 --- a/lib/internal/Magento/Framework/Cache/Backend/Memcached.php +++ b/lib/internal/Magento/Framework/Cache/Backend/Memcached.php @@ -84,8 +84,7 @@ public function save($data, $id, $tags = [], $specificLifetime = false) if (is_string($data) && strlen($data) > $this->_options['slab_size']) { $dataChunks = str_split($data, $this->_options['slab_size']); - $dataChunksCount = count($dataChunks); - for ($i = 0, $cnt = $dataChunksCount; $i < $cnt; $i++) { + for ($i = 0, $count = count($dataChunks); $i < $count; $i++) { $chunkId = $this->_getChunkId($id, $i); if (!parent::save($dataChunks[$i], $chunkId, $tags, $specificLifetime)) { diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 27797d0867924..e0cbab450f6be 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -374,8 +374,7 @@ protected function getVariable($value, $default = '{no_value_defined}') $stackVars = $tokenizer->tokenize(); $result = $default; $last = 0; - $stackVarsCount = count($stackVars); - for ($i = 0; $i < $stackVarsCount; $i++) { + for ($i = 0, $count = count($stackVars); $i < $count; $i++) { if ($i == 0 && isset($this->templateVars[$stackVars[$i]['name']])) { // Getting of template value $stackVars[$i]['variable'] = & $this->templateVars[$stackVars[$i]['name']]; diff --git a/lib/internal/Magento/Framework/System/Ftp.php b/lib/internal/Magento/Framework/System/Ftp.php index c915d50741dd2..14f55f32add82 100644 --- a/lib/internal/Magento/Framework/System/Ftp.php +++ b/lib/internal/Magento/Framework/System/Ftp.php @@ -56,8 +56,7 @@ public function mkdirRecursive($path, $mode = 0777) $dir = explode("/", $path); $path = ""; $ret = true; - $dirCount = count($dir); - for ($i = 0; $i < $dirCount; $i++) { + for ($i = 0, $count = count($dir); $i < $count; $i++) { $path .= "/" . $dir[$i]; if (!@ftp_chdir($this->_conn, $path)) { @ftp_chdir($this->_conn, "/"); diff --git a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php index 9112192f6eb27..6867944d95f8f 100644 --- a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php +++ b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php @@ -31,8 +31,7 @@ protected function _parse() $results = []; preg_match_all(Filter::CONSTRUCTION_PATTERN, $data, $results, PREG_SET_ORDER); - $resultsCount = count($results); - for ($i = 0; $i < $resultsCount; $i++) { + for ($i = 0, $count = count($results); $i < $count; $i++) { if ($results[$i][1] === Filter::TRANS_DIRECTIVE_NAME) { $directive = []; if (preg_match(Filter::TRANS_DIRECTIVE_REGEX, $results[$i][2], $directive) !== 1) { @@ -44,8 +43,7 @@ protected function _parse() } preg_match_all(self::HTML_FILTER, $data, $results, PREG_SET_ORDER); - $resultsCount = count($results); - for ($i = 0; $i < $resultsCount; $i++) { + for ($i = 0, $count = count($results); $i < $count; $i++) { if (!empty($results[$i]['value'])) { $this->_addPhrase($results[$i]['value']); } diff --git a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php index 0f6a402e2609c..6b53a1a4c15b7 100644 --- a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php +++ b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php @@ -22,8 +22,7 @@ protected function _parse() $fileRow = fgets($fileHandle, 4096); $results = []; preg_match_all('/mage\.__\(\s*([\'"])(.*?[^\\\])\1.*?[),]/', $fileRow, $results, PREG_SET_ORDER); - $resultsCount = count($results); - for ($i = 0; $i < $resultsCount; $i++) { + for ($i = 0, $count = count($results); $i < $count; $i++) { if (isset($results[$i][2])) { $quote = $results[$i][1]; $this->_addPhrase($quote . $results[$i][2] . $quote, $lineNumber); @@ -31,8 +30,7 @@ protected function _parse() } preg_match_all('/\\$t\(\s*([\'"])(.*?[^\\\])\1.*?[),]/', $fileRow, $results, PREG_SET_ORDER); - $resultsCount = count($results); - for ($i = 0; $i < $resultsCount; $i++) { + for ($i = 0, $count = count($results); $i < $count; $i++) { if (isset($results[$i][2])) { $quote = $results[$i][1]; $this->_addPhrase($quote . $results[$i][2] . $quote, $lineNumber); From 73ff7cbc55cb1bbde88a96421daa5410f1fdd8c9 Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh721@webkul.com> Date: Sun, 4 Nov 2018 20:33:10 +0530 Subject: [PATCH 649/812] Fixed Product Tax total on PDF for 2.3, Reference of PL #18649 --- app/code/Magento/Weee/Model/Sales/Pdf/Weee.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php b/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php index fa71e81281763..65480047f2f05 100644 --- a/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php +++ b/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php @@ -70,4 +70,17 @@ public function getTotalsForDisplay() return $totals; } + + /** + * Check if we can display Weee total information in PDF + * + * @return bool + */ + public function canDisplay() + { + $items = $this->getSource()->getAllItems(); + $store = $this->getSource()->getStore(); + $amount = $this->_weeeData->getTotalAmounts($items, $store); + return $this->getDisplayZero() === 'true' || $amount != 0; + } } From 5fa66213fa852793694b4aee831bb93969bff5d0 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Sun, 4 Nov 2018 17:20:03 +0200 Subject: [PATCH 650/812] magento/magento2:#18979 - API: Bundle Product Option Repository Delete method removes incorrect option - Fixed failed unit tests --- .../Magento/Bundle/Model/OptionRepository.php | 11 +-- .../Test/Unit/Model/OptionRepositoryTest.php | 74 +++++++++++++++++-- 2 files changed, 73 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Bundle/Model/OptionRepository.php b/app/code/Magento/Bundle/Model/OptionRepository.php index a4d579a44174a..46c44c83b5bb5 100644 --- a/app/code/Magento/Bundle/Model/OptionRepository.php +++ b/app/code/Magento/Bundle/Model/OptionRepository.php @@ -106,17 +106,18 @@ public function get($sku, $optionId) $productLinks = $this->linkManagement->getChildren($product->getSku(), $optionId); - /** @var \Magento\Bundle\Api\Data\OptionInterface $option */ + /** @var \Magento\Bundle\Api\Data\OptionInterface $optionDataObject */ $optionDataObject = $this->optionFactory->create(); $this->dataObjectHelper->populateWithArray( $optionDataObject, $option->getData(), \Magento\Bundle\Api\Data\OptionInterface::class ); - $optionDataObject->setOptionId($option->getId()) - ->setTitle($option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle()) - ->setSku($product->getSku()) - ->setProductLinks($productLinks); + + $optionDataObject->setOptionId($option->getId()); + $optionDataObject->setTitle($option->getTitle() === null ? $option->getDefaultTitle() : $option->getTitle()); + $optionDataObject->setSku($product->getSku()); + $optionDataObject->setProductLinks($productLinks); return $optionDataObject; } diff --git a/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php b/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php index b4a466b413af0..c579d8289d1b6 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php @@ -8,6 +8,7 @@ namespace Magento\Bundle\Test\Unit\Model; use Magento\Bundle\Model\OptionRepository; +use Magento\Framework\Exception\NoSuchEntityException; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -84,7 +85,7 @@ protected function setUp() ->getMock(); $this->optionResourceMock = $this->createPartialMock( \Magento\Bundle\Model\ResourceModel\Option::class, - ['delete', '__wakeup', 'save', 'removeOptionSelections'] + ['get', 'delete', '__wakeup', 'save', 'removeOptionSelections'] ); $this->storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class); $this->linkManagementMock = $this->createMock(\Magento\Bundle\Api\ProductLinkManagementInterface::class); @@ -227,32 +228,91 @@ public function testDeleteThrowsExceptionIfCannotDelete() $this->model->delete($optionMock); } + /** + * Test successful delete action for given $optionId + */ public function testDeleteById() { $productSku = 'sku'; $optionId = 100; - $productMock = $this->createMock(\Magento\Catalog\Api\Data\ProductInterface::class); + + $optionMock = $this->createMock(\Magento\Bundle\Model\Option::class); + $optionMock->expects($this->exactly(2)) + ->method('getId') + ->willReturn($optionId); + + $optionMock->expects($this->once()) + ->method('getData') + ->willReturn([ + 'title' => 'Option title', + 'option_id' => $optionId + ]); + + $this->optionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($optionMock); + + $productMock = $this->createPartialMock( + \Magento\Catalog\Model\Product::class, + ['getTypeId', 'getTypeInstance', 'getStoreId', 'getPriceType', '__wakeup', 'getSku'] + ); $productMock->expects($this->once()) ->method('getTypeId') ->willReturn(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE); - $this->productRepositoryMock->expects($this->once()) + $productMock->expects($this->exactly(2))->method('getSku')->willReturn($productSku); + + $this->productRepositoryMock + ->expects($this->once()) ->method('get') ->with($productSku) ->willReturn($productMock); + $optCollectionMock = $this->createMock(\Magento\Bundle\Model\ResourceModel\Option\Collection::class); + $optCollectionMock->expects($this->once())->method('getItemById')->with($optionId)->willReturn($optionMock); + $this->typeMock->expects($this->once()) + ->method('getOptionsCollection') + ->with($productMock) + ->willReturn($optCollectionMock); + + $this->assertTrue($this->model->deleteById($productSku, $optionId)); + } + + /** + * Tests if NoSuchEntityException thrown when provided $optionId not found + */ + public function testDeleteByIdException() { + $productSku = 'sku'; + $optionId = null; + $optionMock = $this->createMock(\Magento\Bundle\Model\Option::class); + $optionMock->expects($this->exactly(1)) + ->method('getId') + ->willReturn($optionId); + + $productMock = $this->createPartialMock( + \Magento\Catalog\Model\Product::class, + ['getTypeId', 'getTypeInstance', 'getStoreId', 'getPriceType', '__wakeup', 'getSku'] + ); + $productMock->expects($this->once()) + ->method('getTypeId') + ->willReturn(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE); + + $this->productRepositoryMock + ->expects($this->once()) + ->method('get') + ->with($productSku) + ->willReturn($productMock); $optCollectionMock = $this->createMock(\Magento\Bundle\Model\ResourceModel\Option\Collection::class); + $optCollectionMock->expects($this->once())->method('getItemById')->with($optionId)->willReturn($optionMock); $this->typeMock->expects($this->once()) ->method('getOptionsCollection') ->with($productMock) ->willReturn($optCollectionMock); - $optCollectionMock->expects($this->once())->method('setIdFilter')->with($optionId)->willReturnSelf(); - $optCollectionMock->expects($this->once())->method('getFirstItem')->willReturn($optionMock); + $this->expectException(NoSuchEntityException::class); - $this->optionResourceMock->expects($this->once())->method('delete')->with($optionMock)->willReturnSelf(); - $this->assertTrue($this->model->deleteById($productSku, $optionId)); + $this->model->deleteById($productSku, $optionId); } /** From f06056a040a22d49a580fba331cad11799267272 Mon Sep 17 00:00:00 2001 From: Artem Klimov <art.klimoff@gmail.com> Date: Mon, 5 Nov 2018 00:32:38 +0200 Subject: [PATCH 651/812] Sort schema field for test cases --- .../Framework/GraphQl/Config/GraphQlReaderTest.php | 10 ++++++++++ 1 file changed, 10 insertions(+) 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 8583dcf3e4cd2..3d3372429123a 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php @@ -191,6 +191,16 @@ enumValues(includeDeprecated: true) { $mergedSchemaResponseFields = array_merge($schemaResponseFieldsFirstHalf, $schemaResponseFieldsSecondHalf); foreach ($expectedOutput as $searchTerm) { + $sortFields = ['inputFields', 'fields']; + foreach ($sortFields as $sortField) { + isset($searchTerm[$sortField]) && is_array($searchTerm[$sortField]) + ? usort($searchTerm[$sortField], function($a, $b) { + $cmpField = 'name'; + return isset($a[$cmpField]) && isset($b[$cmpField]) + ? strcmp($a[$cmpField], $b[$cmpField]) : 0; + }) : null; + } + $this->assertTrue( (in_array($searchTerm, $mergedSchemaResponseFields)), 'Missing type in the response' From a30501f0d59d42c661a11b009a6eb532dd48de4d Mon Sep 17 00:00:00 2001 From: Vlad Veselov <orlangur@users.noreply.github.com> Date: Mon, 5 Nov 2018 00:45:12 +0200 Subject: [PATCH 652/812] Add `count` call back --- .../Multishipping/Test/TestStep/FillShippingInformationStep.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php b/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php index 73b2f762057b0..2c41ce3d8b4e2 100644 --- a/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php +++ b/dev/tests/functional/tests/app/Magento/Multishipping/Test/TestStep/FillShippingInformationStep.php @@ -58,7 +58,7 @@ public function __construct( public function run() { $shippingMethods = []; - for ($i = 0, $count = $this->customer->getAddress(); $i < $count; $i++) { + for ($i = 0, $count = count($this->customer->getAddress()); $i < $count; $i++) { $shippingMethods[] = $this->shippingMethod; } $this->shippingInformation->getShippingBlock()->selectShippingMethod($shippingMethods); From 0f575bce67a6dbc4fd9226d7b0ef19eaaebe0fed Mon Sep 17 00:00:00 2001 From: larsroettig <l.roettig@techdivision.com> Date: Mon, 5 Nov 2018 00:19:04 +0100 Subject: [PATCH 653/812] #18956 Fix for phpunit-test case --- .../Magento/Store/Model/Config/Importer/Processor/Create.php | 4 ++-- .../Test/Unit/Model/Config/Importer/Processor/CreateTest.php | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php index 9d1a7a38ede68..71ffa5303293d 100644 --- a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php +++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php @@ -177,8 +177,8 @@ private function createGroups(array $items, array $data) ); $group = $this->groupFactory->create(); - if (!isset($groupData['root_categry_id'])) { - $groupData['root_categry_id'] = 0; + if (!isset($groupData['root_category_id'])) { + $groupData['root_category_id'] = 0; } $group->setData($groupData); diff --git a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php index 2c2b0b00aec43..0901464224399 100644 --- a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php @@ -291,9 +291,6 @@ public function testRunGroup() $this->groupMock->expects($this->exactly(3)) ->method('getResource') ->willReturn($this->abstractDbMock); - $this->groupMock->expects($this->once()) - ->method('setRootCategoryId') - ->with(0); $this->groupMock->expects($this->once()) ->method('getDefaultStoreId') ->willReturn($defaultStoreId); From a38250ec547c80e6558e571317f595673efeebb2 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Mon, 5 Nov 2018 10:51:53 +0200 Subject: [PATCH 654/812] magento-engcom/magento2ce#2299: Code style fixes --- .../Magento/Catalog/Model/AbstractModel.php | 13 ++--- .../Magento/Sales/Model/Order/Address.php | 56 +++++++++---------- .../Magento/Widget/Block/BlockInterface.php | 1 + 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/app/code/Magento/Catalog/Model/AbstractModel.php b/app/code/Magento/Catalog/Model/AbstractModel.php index 5faf6ccbcdef9..78a49cd1e8b14 100644 --- a/app/code/Magento/Catalog/Model/AbstractModel.php +++ b/app/code/Magento/Catalog/Model/AbstractModel.php @@ -282,9 +282,9 @@ public function getWebsiteStoreIds() * * Default value existing is flag for using store value in data * - * @param string $attributeCode - * @param mixed $value - * @return $this + * @param string $attributeCode + * @param mixed $value + * @return $this * * @deprecated 101.0.0 */ @@ -332,11 +332,10 @@ public function getAttributeDefaultValue($attributeCode) } /** - * Set attribute code flag if attribute has value in current store and does not use - * value of default store as value + * Set attribute code flag if attribute has value in current store and does not use value of default store as value * - * @param string $attributeCode - * @return $this + * @param string $attributeCode + * @return $this * * @deprecated 101.0.0 */ diff --git a/app/code/Magento/Sales/Model/Order/Address.php b/app/code/Magento/Sales/Model/Order/Address.php index 8bc602c75db4d..083ec0089a5c0 100644 --- a/app/code/Magento/Sales/Model/Order/Address.php +++ b/app/code/Magento/Sales/Model/Order/Address.php @@ -173,7 +173,7 @@ protected function implodeStreetValue($value) * Enforce format of the street field * * @param array|string $key - * @param null $value + * @param array|string $value * @return $this */ public function setData($key, $value = null) @@ -508,7 +508,7 @@ public function getVatRequestSuccess() } /** - * {@inheritdoc} + * @inheritdoc */ public function setParentId($id) { @@ -516,7 +516,7 @@ public function setParentId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomerAddressId($id) { @@ -524,7 +524,7 @@ public function setCustomerAddressId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegionId($id) { @@ -532,7 +532,7 @@ public function setRegionId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setStreet($street) { @@ -540,7 +540,7 @@ public function setStreet($street) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCustomerId($id) { @@ -548,7 +548,7 @@ public function setCustomerId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setFax($fax) { @@ -556,7 +556,7 @@ public function setFax($fax) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegion($region) { @@ -564,7 +564,7 @@ public function setRegion($region) } /** - * {@inheritdoc} + * @inheritdoc */ public function setPostcode($postcode) { @@ -572,7 +572,7 @@ public function setPostcode($postcode) } /** - * {@inheritdoc} + * @inheritdoc */ public function setLastname($lastname) { @@ -580,7 +580,7 @@ public function setLastname($lastname) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCity($city) { @@ -588,7 +588,7 @@ public function setCity($city) } /** - * {@inheritdoc} + * @inheritdoc */ public function setEmail($email) { @@ -596,7 +596,7 @@ public function setEmail($email) } /** - * {@inheritdoc} + * @inheritdoc */ public function setTelephone($telephone) { @@ -604,7 +604,7 @@ public function setTelephone($telephone) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCountryId($id) { @@ -612,7 +612,7 @@ public function setCountryId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setFirstname($firstname) { @@ -620,7 +620,7 @@ public function setFirstname($firstname) } /** - * {@inheritdoc} + * @inheritdoc */ public function setAddressType($addressType) { @@ -628,7 +628,7 @@ public function setAddressType($addressType) } /** - * {@inheritdoc} + * @inheritdoc */ public function setPrefix($prefix) { @@ -636,7 +636,7 @@ public function setPrefix($prefix) } /** - * {@inheritdoc} + * @inheritdoc */ public function setMiddlename($middlename) { @@ -644,7 +644,7 @@ public function setMiddlename($middlename) } /** - * {@inheritdoc} + * @inheritdoc */ public function setSuffix($suffix) { @@ -652,7 +652,7 @@ public function setSuffix($suffix) } /** - * {@inheritdoc} + * @inheritdoc */ public function setCompany($company) { @@ -660,7 +660,7 @@ public function setCompany($company) } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatId($id) { @@ -668,7 +668,7 @@ public function setVatId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatIsValid($vatIsValid) { @@ -676,7 +676,7 @@ public function setVatIsValid($vatIsValid) } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatRequestId($id) { @@ -684,7 +684,7 @@ public function setVatRequestId($id) } /** - * {@inheritdoc} + * @inheritdoc */ public function setRegionCode($regionCode) { @@ -692,7 +692,7 @@ public function setRegionCode($regionCode) } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatRequestDate($vatRequestDate) { @@ -700,7 +700,7 @@ public function setVatRequestDate($vatRequestDate) } /** - * {@inheritdoc} + * @inheritdoc */ public function setVatRequestSuccess($vatRequestSuccess) { @@ -708,7 +708,7 @@ public function setVatRequestSuccess($vatRequestSuccess) } /** - * {@inheritdoc} + * @inheritdoc * * @return \Magento\Sales\Api\Data\OrderAddressExtensionInterface|null */ @@ -718,7 +718,7 @@ public function getExtensionAttributes() } /** - * {@inheritdoc} + * @inheritdoc * * @param \Magento\Sales\Api\Data\OrderAddressExtensionInterface $extensionAttributes * @return $this diff --git a/app/code/Magento/Widget/Block/BlockInterface.php b/app/code/Magento/Widget/Block/BlockInterface.php index db101b5e81adc..4f795d949b8cd 100644 --- a/app/code/Magento/Widget/Block/BlockInterface.php +++ b/app/code/Magento/Widget/Block/BlockInterface.php @@ -19,6 +19,7 @@ interface BlockInterface { /** * Add data to the widget. + * * Retains previous data in the widget. * * @param array $arr From f9b4595a60d7b81775cdd43f996991acb0d50ff2 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Mon, 5 Nov 2018 12:08:27 +0300 Subject: [PATCH 655/812] MAGETWO-91750: Multiselect attribute values is not searchable under Quick Search when more than one value is selected - Fix perfomance --- .../Model/Indexer/Fulltext/Action/DataProvider.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 421746e7761c1..6cd4e227b85c8 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -653,7 +653,8 @@ private function getAttributeOptionValue($attributeId, $valueIds, $storeId) } } foreach ($attributeValueIds as $attrValueId) { - $attributeOptionValue .= $this->attributeOptions[$optionKey][$attrValueId] . ' '; + if (isset($this->attributeOptions[$optionKey][$attrValueId])) + $attributeOptionValue .= $this->attributeOptions[$optionKey][$attrValueId] . ' '; } return empty($attributeOptionValue) ? null : trim($attributeOptionValue); } From da66589239c95d7739b2c01e27628d178ed9c139 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Mon, 5 Nov 2018 12:32:18 +0300 Subject: [PATCH 656/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix functional test --- .../Mftf/Section/AdminProductFormGroupedProductsSection.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml index 0739c4e601b62..f5549f26bfd56 100644 --- a/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml @@ -11,8 +11,8 @@ <section name="AdminProductFormGroupedProductsSection"> <element name="toggleGroupedProduct" type="button" selector="div[data-index=grouped] .admin__collapsible-title"/> <element name="addProductsToGroup" type="button" selector="button[data-index='grouped_products_button']" timeout="30"/> - <element name="nextActionButton" type="button" selector="//button[@class='action-next']"/> - <element name="previousActionButton" type="button" selector="//button[@class='action-previous']"/> + <element name="nextActionButton" type="button" selector=".admin__field > .admin__field-control > .admin__control-table-pagination > .admin__data-grid-pager > .action-next"/> + <element name="previousActionButton" type="button" selector=".admin__field > .admin__field-control > .admin__control-table-pagination > .admin__data-grid-pager > .action-previous"/> <element name="positionProduct" type="input" selector="//tbody/tr[{{arg}}][contains(@class,'data-row')]/td[10]//input[@class='position-widget-input']" parameterized="true"/> <element name="nameProductFromGrid" type="text" selector="//tbody/tr[{{arg}}][contains(@class,'data-row')]/td[4]//*[@class='admin__field-control']//span" parameterized="true"/> </section> From 1a703c7054e3efc51cf9eded93602c6d4b93f726 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Mon, 5 Nov 2018 13:11:11 +0300 Subject: [PATCH 657/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../adminhtml/web/js/grouped-product-grid.js | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index f257cb2df729e..c8e5a58c99e78 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -23,6 +23,7 @@ define([ if (position || position === 0) { this.checkMaxPosition(position); this.sort(position, elem); + if (~~position === this.maxPosition && ~~position > this.getDefaultPageBoundary() + 1) { this.shiftNextPagesPositions(position); } @@ -37,17 +38,17 @@ define([ * @param position */ shiftNextPagesPositions: function (position) { - var recordData = this.recordData(); + + var recordData = this.recordData(), + startIndex = ~~this.currentPage() * this.pageSize, + offset = position - startIndex + 1; if (~~this.currentPage() === this.pages()) { return false; - } else { - var startIndex = ~~this.currentPage() * this.pageSize, - offset = position - startIndex + 1; - for (var index = startIndex; index < recordData.length; index++) { - recordData[index].position = index + offset; - } - this.recordData(recordData); } + for (var index = startIndex; index < recordData.length; index++) { + recordData[index].position = index + offset; + } + this.recordData(recordData); }, @@ -58,14 +59,14 @@ define([ * @param event */ updateGridPosition: function (data, event) { - var inputValue = parseInt(event.target.value), + var inputValue = parseInt(event.target.value, 10), recordData = this.recordData(), record, previousValue, updatedRecord; record = this.elems().find(function (obj) { - return obj.dataScope === data.parentScope + return obj.dataScope === data.parentScope; }); previousValue = this.getCalculatedPosition(record); @@ -105,7 +106,7 @@ define([ */ getUpdatedRecordIndex: function (recordData, recordId) { return recordData.map(function (o) { - return ~~o.id + return ~~o.id; }).indexOf(~~recordId); }, @@ -163,7 +164,7 @@ define([ this.elems([]); updatedRecord = this.getUpdatedRecordIndex(recordData, objectToUpdate.data().id); recordData.forEach(function (value, index) { - recordData[index].position = (index === updatedRecord) ? 0 : value.position + 1; + recordData[index].position = index === updatedRecord ? 0 : value.position + 1; }); this.reloadGridData(recordData); } @@ -198,7 +199,7 @@ define([ * @return {number} */ getDefaultPageBoundary: function () { - return (~~this.currentPage() * this.pageSize) - 1; + return ~~this.currentPage() * this.pageSize - 1; }, /** @@ -208,7 +209,7 @@ define([ */ getGlobalMaxPosition: function () { return _.max(this.recordData().map(function (r) { - return ~~r.position + return ~~r.position; })); } }); From a089fa137b790ef5be815eee7672baabc00b8755 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Mon, 5 Nov 2018 13:29:39 +0200 Subject: [PATCH 658/812] ENGCOM-3283: Feature/import success page improvement #138 Fix functional tests. --- .../ImportExport/Test/Constraint/AssertImportSuccessMessage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/ImportExport/Test/Constraint/AssertImportSuccessMessage.php b/dev/tests/functional/tests/app/Magento/ImportExport/Test/Constraint/AssertImportSuccessMessage.php index ca75e3b203f63..a5408426514f2 100644 --- a/dev/tests/functional/tests/app/Magento/ImportExport/Test/Constraint/AssertImportSuccessMessage.php +++ b/dev/tests/functional/tests/app/Magento/ImportExport/Test/Constraint/AssertImportSuccessMessage.php @@ -28,7 +28,7 @@ class AssertImportSuccessMessage extends AbstractConstraint public function processAssert(AdminImportIndex $adminImportIndex) { $validationMessage = $adminImportIndex->getMessagesBlock()->getImportResultMessage(); - \PHPUnit\Framework\Assert::assertEquals( + \PHPUnit\Framework\Assert::assertStringEndsWith( self::SUCCESS_MESSAGE, $validationMessage, 'Wrong validation result is displayed.' From 2f995d13c332dd4a2e560373d231c0f06cf25f98 Mon Sep 17 00:00:00 2001 From: Tobias Maile <tobias.maile@brandung.de> Date: Mon, 5 Nov 2018 12:33:25 +0100 Subject: [PATCH 659/812] GraphQL-202: [Mutations] adds description and category_id as parameter --- app/code/Magento/SendFriendGraphQl/etc/schema.graphqls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls index 87bf90fd10072..4123387650838 100644 --- a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls @@ -2,7 +2,7 @@ # See COPYING.txt for license details. type Mutation { - sendEmailToFriend (input: SendEmailToFriendSenderInput): SendEmailToFriendOutput @resolver(class: "\\Magento\\SendFriendGraphQl\\Model\\Resolver\\SendEmailToFriend") @doc(description:"@todo") + sendEmailToFriend (input: SendEmailToFriendSenderInput): SendEmailToFriendOutput @resolver(class: "\\Magento\\SendFriendGraphQl\\Model\\Resolver\\SendEmailToFriend") @doc(description:"Recommends Product by Sending Single/Multiple Email") } input SendEmailToFriendSenderInput { @@ -16,9 +16,9 @@ type Sender { email: String! message: String! } -#@todo Prams can be removed if dispatching of event in app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php not needed type Params { product_id: Int! + category_id: Int! } type Recipient { From 1fb624d381e67581a06e66809883e51a4a4b0d75 Mon Sep 17 00:00:00 2001 From: Tobias Maile <tobias.maile@brandung.de> Date: Mon, 5 Nov 2018 12:34:46 +0100 Subject: [PATCH 660/812] GraphQL-202: [Mutations] moves validation logic to separate module --- .../Model/Validation/Validation.php | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php diff --git a/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php b/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php new file mode 100644 index 0000000000000..49f7feeaba489 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php @@ -0,0 +1,69 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\SendFriendGraphQl\Model\Validation; + +use Magento\Framework\DataObjectFactory; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\SendFriend\Model\SendFriend; + +class Validation +{ + /** + * @var SendFriend + */ + private $sendFriend; + /** + * @var DataObjectFactory + */ + private $dataObjectFactory; + + public function __construct( + DataObjectFactory $dataObjectFactory, + SendFriend $sendFriend + ) { + $this->sendFriend = $sendFriend; + $this->dataObjectFactory = $dataObjectFactory; + } + + /** + * @param $args + * @param array $recipientsArray + * @throws GraphQlInputException + */ + public function validate($args, array $recipientsArray): void + { + $this->prepareDataForSendFriendValidation($args, $recipientsArray); + $validationResult = $this->sendFriend->validate(); + if ($validationResult !== true) { + throw new GraphQlInputException(__(implode($validationResult))); + } + if ($this->sendFriend->getMaxSendsToFriend() && $this->sendFriend->isExceedLimit()) { + throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', + $this->sendFriend->getMaxSendsToFriend() + )); + } + } + + private function prepareDataForSendFriendValidation(array $args, array $recipientsArray): void + { + $sender = $this->dataObjectFactory->create()->setData([ + 'name' => $args['input']['sender']['name'], + 'email'=> $args['input']['sender']['email'], + 'message' => $args['input']['sender']['message'], + ]); + $emails = []; + foreach ($recipientsArray['recipients'] as $recipient) { + $emails[] = $recipient['email']; + } + $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + + $this->sendFriend->setData('_sender', $sender); + $this->sendFriend->setData('_recipients', $recipients); + } + +} \ No newline at end of file From ed6649194f0844f8faae0ba63a5df52b3fe8d5c4 Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi <yevhenii.dumskyi@gmail.com> Date: Mon, 5 Nov 2018 14:34:03 +0200 Subject: [PATCH 661/812] Add additional check if password hash is empty in auth process --- app/code/Magento/Customer/Model/Authentication.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/Authentication.php b/app/code/Magento/Customer/Model/Authentication.php index 0967f1a0189e3..b0729647d7eec 100644 --- a/app/code/Magento/Customer/Model/Authentication.php +++ b/app/code/Magento/Customer/Model/Authentication.php @@ -167,7 +167,7 @@ public function authenticate($customerId, $password) { $customerSecure = $this->customerRegistry->retrieveSecureData($customerId); $hash = $customerSecure->getPasswordHash(); - if (!$this->encryptor->validateHash($password, $hash)) { + if (!$hash || !$this->encryptor->validateHash($password, $hash)) { $this->processAuthenticationFailure($customerId); if ($this->isLocked($customerId)) { throw new UserLockedException(__('The account is locked.')); From 2a021c075f52e39b03dc8c30ba418afc57851041 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Mon, 5 Nov 2018 17:12:32 +0300 Subject: [PATCH 662/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../view/adminhtml/web/js/grouped-product-grid.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index c8e5a58c99e78..3fb7e9ecc8b4b 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -35,17 +35,19 @@ define([ /** * Shift positions for next page elements * - * @param position + * @param {Number} position */ shiftNextPagesPositions: function (position) { var recordData = this.recordData(), startIndex = ~~this.currentPage() * this.pageSize, - offset = position - startIndex + 1; + offset = position - startIndex + 1, + index = startIndex; + if (~~this.currentPage() === this.pages()) { return false; } - for (var index = startIndex; index < recordData.length; index++) { + for (index; index < recordData.length; index++) { recordData[index].position = index + offset; } this.recordData(recordData); From e18bcb5f846df4ae8fd84f2b66890984982aee04 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Mon, 5 Nov 2018 17:15:28 +0300 Subject: [PATCH 663/812] MAGETWO-91750: Multiselect attribute values is not searchable under Quick Search when more than one value is selected - Fix static testd --- .../Model/Indexer/Fulltext/Action/DataProvider.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 6cd4e227b85c8..39cb95747c2cf 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -653,8 +653,9 @@ private function getAttributeOptionValue($attributeId, $valueIds, $storeId) } } foreach ($attributeValueIds as $attrValueId) { - if (isset($this->attributeOptions[$optionKey][$attrValueId])) + if (isset($this->attributeOptions[$optionKey][$attrValueId])) { $attributeOptionValue .= $this->attributeOptions[$optionKey][$attrValueId] . ' '; + } } return empty($attributeOptionValue) ? null : trim($attributeOptionValue); } From a40eb487b7d3f57d6241620ff2f49d9b4196f383 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Mon, 5 Nov 2018 10:42:57 -0600 Subject: [PATCH 664/812] ENGCOM-3355: [Forwardport] Fix Authenticating a customer via REST API does not update the last logged in data #18973 - Fixed docblocks --- app/code/Magento/Integration/Model/CustomerTokenService.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Integration/Model/CustomerTokenService.php b/app/code/Magento/Integration/Model/CustomerTokenService.php index 35d0424d3b4fa..7c2c444a734eb 100644 --- a/app/code/Magento/Integration/Model/CustomerTokenService.php +++ b/app/code/Magento/Integration/Model/CustomerTokenService.php @@ -16,6 +16,9 @@ use Magento\Framework\Exception\AuthenticationException; use Magento\Framework\Event\ManagerInterface; +/** + * @inheritdoc + */ class CustomerTokenService implements \Magento\Integration\Api\CustomerTokenServiceInterface { /** @@ -79,7 +82,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function createCustomerAccessToken($username, $password) { From 90831f56053bc2af291468e01bead189441eb25c Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Mon, 5 Nov 2018 19:16:24 +0200 Subject: [PATCH 665/812] graphQl: removed not needed exception, added test coverage --- .../Model/Cart/SetShippingAddressOnCart.php | 9 +- .../Quote/SetShippingAddressOnCartTest.php | 424 ++++++++++++++++++ 2 files changed, 425 insertions(+), 8 deletions(-) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php index 43e58bb807672..a2d93ac1753c5 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php @@ -84,19 +84,12 @@ public function setAddresses(ContextInterface $context, int $cartId, array $ship if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { throw new GraphQlAuthorizationException( __( - 'Address management allowed only for authorized customers' + 'Address management allowed only for authorized customers.' ) ); } /** @var AddressInterface $customerAddress */ $customerAddress = $this->addressRepository->getById($customerAddressId); - if ($context->getUserId() !== (int)$customerAddress->getCustomerId()) { - throw new GraphQlInputException( - __( - 'Address is not applicable for current customer' - ) - ); - } $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); } else { $shippingAddress = $this->addressModel->addData($addressInput); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php new file mode 100644 index 0000000000000..9771dbbf84c48 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php @@ -0,0 +1,424 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Quote; + +use Magento\Integration\Api\CustomerTokenServiceInterface; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface; +use Magento\Quote\Model\ResourceModel\Quote as QuoteResource; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQlAbstract; +use Magento\TestFramework\ObjectManager; + +/** + * Test for set shipping addresses on cart mutation + */ +class SetShippingAddressOnCartTest extends GraphQlAbstract +{ + /** + * @var QuoteResource + */ + private $quoteResource; + + /** + * @var Quote + */ + private $quote; + + /** + * @var QuoteIdToMaskedQuoteIdInterface + */ + private $quoteIdToMaskedId; + + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $this->quoteResource = $objectManager->create(QuoteResource::class); + $this->quote = $objectManager->create(Quote::class); + $this->quoteIdToMaskedId = $objectManager->create(QuoteIdToMaskedQuoteIdInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + */ + public function testSetNewGuestShippingAddressOnCart() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + address: { + firstname: "test firstname" + lastname: "test lastname" + company: "test company" + street: ["test street 1", "test street 2"] + city: "test city" + region: "test region" + postcode: "887766" + country_code: "US" + telephone: "88776655" + save_in_address_book: false + } + } + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']); + $cartResponse = $response['setShippingAddressesOnCart']['cart']; + self::assertArrayHasKey('addresses', $cartResponse); + $shippingAddressResponse = current($cartResponse['addresses']); + $this->assertNewShippingAddressFields($shippingAddressResponse); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + */ + public function testSetSavedShippingAddressOnCartByGuest() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + customer_address_id: 1 + } + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + self::expectExceptionMessage('Address management allowed only for authorized customers.'); + $this->graphQlQuery($query); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + */ + public function testSetSavedAndNewShippingAddressOnCartAtTheSameTime() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + customer_address_id: 1, + address: { + firstname: "test firstname" + lastname: "test lastname" + company: "test company" + street: ["test street 1", "test street 2"] + city: "test city" + region: "test region" + postcode: "887766" + country_code: "US" + telephone: "88776655" + save_in_address_book: false + } + } + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + self::expectExceptionMessage( + 'Shipping address can\'t contain "customer_address_id" and "address" input at the same time.' + ); + $this->graphQlQuery($query); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + */ + public function testSetShippingAddressOnCartWithNoAddresses() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + {} + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + self::expectExceptionMessage( + 'Shipping address should contain either "customer_address_id" or "address" input.' + ); + $this->graphQlQuery($query); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @magentoApiDataFixture Magento/Customer/_files/customer.php + */ + public function testSetNewRegisteredCustomerShippingAddressOnCart() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $this->quote->setCustomerId(1); + $this->quoteResource->save($this->quote); + + $headerMap = $this->getHeaderMap(); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + address: { + firstname: "test firstname" + lastname: "test lastname" + company: "test company" + street: ["test street 1", "test street 2"] + city: "test city" + region: "test region" + postcode: "887766" + country_code: "US" + telephone: "88776655" + save_in_address_book: false + } + } + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query, [], '', $headerMap); + + self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']); + $cartResponse = $response['setShippingAddressesOnCart']['cart']; + self::assertArrayHasKey('addresses', $cartResponse); + $shippingAddressResponse = current($cartResponse['addresses']); + $this->assertNewShippingAddressFields($shippingAddressResponse); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Customer/_files/customer_two_addresses.php + */ + public function testSetSavedRegisteredCustomerShippingAddressOnCart() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $this->quote->setCustomerId(1); + $this->quoteResource->save($this->quote); + + $headerMap = $this->getHeaderMap(); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + customer_address_id: 1 + } + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query, [], '', $headerMap); + + self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']); + $cartResponse = $response['setShippingAddressesOnCart']['cart']; + self::assertArrayHasKey('addresses', $cartResponse); + $shippingAddressResponse = current($cartResponse['addresses']); + $this->assertSavedShippingAddressFields($shippingAddressResponse); + } + + /** + * Verify the all the whitelisted fields for a New Address Object + * + * @param array $shippingAddressResponse + */ + private function assertNewShippingAddressFields(array $shippingAddressResponse): void + { + $assertionMap = [ + ['response_field' => 'firstname', 'expected_value' => 'test firstname'], + ['response_field' => 'lastname', 'expected_value' => 'test lastname'], + ['response_field' => 'company', 'expected_value' => 'test company'], + ['response_field' => 'street', 'expected_value' => [0 => 'test street 1', 1 => 'test street 2']], + ['response_field' => 'city', 'expected_value' => 'test city'], + ['response_field' => 'postcode', 'expected_value' => '887766'], + ['response_field' => 'telephone', 'expected_value' => '88776655'] + ]; + + $this->assertResponseFields($shippingAddressResponse, $assertionMap); + } + + /** + * Verify the all the whitelisted fields for a Address Object + * + * @param array $shippingAddressResponse + */ + private function assertSavedShippingAddressFields(array $shippingAddressResponse): void + { + $assertionMap = [ + ['response_field' => 'firstname', 'expected_value' => 'John'], + ['response_field' => 'lastname', 'expected_value' => 'Smith'], + ['response_field' => 'company', 'expected_value' => 'CompanyName'], + ['response_field' => 'street', 'expected_value' => [0 => 'Green str, 67']], + ['response_field' => 'city', 'expected_value' => 'CityM'], + ['response_field' => 'postcode', 'expected_value' => '75477'], + ['response_field' => 'telephone', 'expected_value' => '3468676'] + ]; + + $this->assertResponseFields($shippingAddressResponse, $assertionMap); + } + + /** + * @param string $username + * @return array + */ + private function getHeaderMap(string $username = 'customer@example.com'): array + { + $password = 'password'; + /** @var CustomerTokenServiceInterface $customerTokenService */ + $customerTokenService = ObjectManager::getInstance() + ->get(CustomerTokenServiceInterface::class); + $customerToken = $customerTokenService->createCustomerAccessToken($username, $password); + $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; + return $headerMap; + } +} From 5d2b1c8d80f23a8061c63702d370728d05234cd5 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Mon, 5 Nov 2018 19:17:53 +0200 Subject: [PATCH 666/812] graphQl: fixed dependency issue --- app/code/Magento/QuoteGraphQl/composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index c9900dd5f3150..485c958718bf3 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -7,7 +7,8 @@ "magento/framework": "*", "magento/module-quote": "*", "magento/module-catalog": "*", - "magento/module-store": "*" + "magento/module-store": "*", + "magento/module-checkout": "*" }, "suggest": { "magento/module-graph-ql": "*" From 743d3ebd5584b61b3c3d1ff804767871caff470c Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Mon, 5 Nov 2018 11:46:52 -0600 Subject: [PATCH 667/812] MAGETWO-95248: Show Packages button in Shipping and Tracking information section of Shipments doesn't work --- .../view/adminhtml/web/js/packages.js | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 app/code/Magento/Shipping/view/adminhtml/web/js/packages.js diff --git a/app/code/Magento/Shipping/view/adminhtml/web/js/packages.js b/app/code/Magento/Shipping/view/adminhtml/web/js/packages.js new file mode 100644 index 0000000000000..f46ad4192d170 --- /dev/null +++ b/app/code/Magento/Shipping/view/adminhtml/web/js/packages.js @@ -0,0 +1,39 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'jquery', + 'Magento_Ui/js/modal/modal', + 'mage/translate' +], function ($, modal, $t) { + 'use strict'; + + return function (config, element) { + config.buttons = [ + { + text: $t('Print'), + 'class': 'action action-primary', + + /** + * Click handler + */ + click: function () { + window.location.href = this.options.url; + } + }, { + text: $t('Cancel'), + 'class': 'action action-secondary', + + /** + * Click handler + */ + click: function () { + this.closeModal(); + } + } + ]; + modal(config, element); + }; +}); From 3343ad61aa8ac0d596f5b6783b25852d8589f966 Mon Sep 17 00:00:00 2001 From: Dmytro Drozd <ddrozd@magento.com> Date: Mon, 5 Nov 2018 20:41:11 +0200 Subject: [PATCH 668/812] MAGETWO-96026: Create MFTF test for MAGETWO-93973. Add more stability --- ...PricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml index 6eb78809b187d..a8b2df1fcfa67 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/TieredPricingAndQuantityIncrementsWorkWithDecimalinventoryTest.xml @@ -63,7 +63,9 @@ <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrementsUseConfigSettings}}" stepKey="clickOnEnableQtyIncrementsUseConfigSettingsCheckbox"/> <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrements}}" stepKey="clickOnEnableQtyIncrements"/> <click selector="{{AdminProductFormAdvancedInventorySection.enableQtyIncrementsOptions(('1'))}}" stepKey="chooseYesOnEnableQtyIncrements"/> + <scrollTo selector="{{AdminProductFormAdvancedInventorySection.qtyIncrementsUseConfigSettings}}" stepKey="scrollToQtyIncrementsUseConfigSettings"/> <click selector="{{AdminProductFormAdvancedInventorySection.qtyIncrementsUseConfigSettings}}" stepKey="clickOnQtyIncrementsUseConfigSettings"/> + <scrollTo selector="{{AdminProductFormAdvancedInventorySection.qtyIncrements}}" stepKey="scrollToQtyIncrements"/> <fillField selector="{{AdminProductFormAdvancedInventorySection.qtyIncrements}}" userInput=".5" stepKey="fillQtyIncrements"/> <!--Step6. Close *Advanced Inventory* (Click on button *Done*). Save *prod1* (Click on button *Save*) --> <click selector="{{AdminProductFormAdvancedInventorySection.doneButton}}" stepKey="clickOnDoneButton3"/> From e1f09fb984df705e35dde07092d04957c7c0e5c1 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Mon, 5 Nov 2018 21:15:25 +0200 Subject: [PATCH 669/812] graphQl: added extension point for multishipping --- .../Model/Cart/SetShippingAddressesOnCart.php | 48 +++++++++++++++++++ .../SingleShippingAddressProcessor.php} | 20 +++----- .../SetShippingAddressesOnCartInterface.php | 31 ++++++++++++ .../Resolver/SetShippingAddressesOnCart.php | 22 ++++----- .../Magento/QuoteGraphQl/etc/graphql/di.xml | 9 ++++ 5 files changed, 106 insertions(+), 24 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php rename app/code/Magento/QuoteGraphQl/Model/Cart/{SetShippingAddressOnCart.php => SetShippingAddressesOnCart/SingleShippingAddressProcessor.php} (85%) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php new file mode 100644 index 0000000000000..ad3615b94f8ef --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Cart; + +use InvalidArgumentException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; + +/** + * Set shipping addresses for shopping cart processors chain + */ +class SetShippingAddressesOnCart implements SetShippingAddressesOnCartInterface +{ + /** + * @var SetShippingAddressesOnCartInterface[] + */ + private $shippingAddressProcessors; + + /** + * @param array $shippingAddressProcessors + */ + public function __construct( + array $shippingAddressProcessors + ) { + $this->shippingAddressProcessors = $shippingAddressProcessors; + } + + /** + * @inheritdoc + */ + public function execute(ContextInterface $context, int $cartId, array $shippingAddresses): void + { + foreach ($this->shippingAddressProcessors as $shippingAddressProcessor) { + if (!$shippingAddressProcessor instanceof SetShippingAddressesOnCartInterface) { + throw new InvalidArgumentException( + get_class($shippingAddressProcessor) . + ' is not instance of \Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface.' + ); + } + + $shippingAddressProcessor->execute($context, $cartId, $shippingAddresses); + } + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php similarity index 85% rename from app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php rename to app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php index a2d93ac1753c5..6584b9887bed5 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\QuoteGraphQl\Model\Cart; +namespace Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCart; use Magento\Authorization\Model\UserContextInterface; use Magento\Customer\Api\Data\AddressInterface; @@ -15,13 +15,12 @@ use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface; /** - * Class SetShippingAddressOnCart - * - * Set shipping address for a specified shopping cart + * Set single shipping address for a specified shopping cart */ -class SetShippingAddressOnCart +class SingleShippingAddressProcessor implements SetShippingAddressesOnCartInterface { /** * @var ShippingAddressManagementInterface @@ -54,17 +53,12 @@ public function __construct( } /** - * @param ContextInterface $context - * @param int $cartId - * @param array $shippingAddresses - * @return void + * @inheritdoc */ - public function setAddresses(ContextInterface $context, int $cartId, array $shippingAddresses): void + public function execute(ContextInterface $context, int $cartId, array $shippingAddresses): void { if (count($shippingAddresses) > 1) { - throw new GraphQlInputException( - __('Multiple address does not allowed here!') - ); + return; } $shippingAddress = current($shippingAddresses); $customerAddressId = $shippingAddress['customer_address_id'] ?? null; diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php new file mode 100644 index 0000000000000..f9623e36c5395 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Cart; + +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; + +/** + * Extension point for setting shipping addresses for a specified shopping cart + * + * All objects that are responsible for set shipping addresses on cart via GraphQl should implement this interface. + */ +interface SetShippingAddressesOnCartInterface +{ + + /** + * Set shipping addresses for a specified shopping cart + * + * @param ContextInterface $context + * @param int $cartId + * @param array $shippingAddresses + * @return void + * @throws GraphQlInputException + */ + public function execute(ContextInterface $context, int $cartId, array $shippingAddresses): void; +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php index fcb4255a75eb7..ec151214dbc42 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php @@ -15,7 +15,7 @@ use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; -use Magento\QuoteGraphQl\Model\Cart\SetShippingAddressOnCart; +use Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface; /** * Class SetShippingAddressesOnCart @@ -29,11 +29,6 @@ class SetShippingAddressesOnCart implements ResolverInterface */ private $maskedQuoteIdToQuoteId; - /** - * @var SetShippingAddressOnCart - */ - private $setShippingAddressOnCart; - /** * @var ShippingAddressManagementInterface */ @@ -49,25 +44,30 @@ class SetShippingAddressesOnCart implements ResolverInterface */ private $arrayManager; + /** + * @var SetShippingAddressesOnCartInterface + */ + private $setShippingAddressesOnCart; + /** * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId - * @param SetShippingAddressOnCart $setShippingAddressOnCart * @param ShippingAddressManagementInterface $shippingAddressManagement * @param GetCartForUser $getCartForUser * @param ArrayManager $arrayManager + * @param SetShippingAddressesOnCartInterface $setShippingAddressesOnCart */ public function __construct( MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, - SetShippingAddressOnCart $setShippingAddressOnCart, ShippingAddressManagementInterface $shippingAddressManagement, GetCartForUser $getCartForUser, - ArrayManager $arrayManager + ArrayManager $arrayManager, + SetShippingAddressesOnCartInterface $setShippingAddressesOnCart ) { $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->setShippingAddressOnCart = $setShippingAddressOnCart; $this->shippingAddressManagement = $shippingAddressManagement; $this->getCartForUser = $getCartForUser; $this->arrayManager = $arrayManager; + $this->setShippingAddressesOnCart = $setShippingAddressesOnCart; } /** @@ -89,7 +89,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId()); $cartId = (int)$cart->getEntityId(); - $this->setShippingAddressOnCart->setAddresses($context, $cartId, $shippingAddresses); + $this->setShippingAddressesOnCart->execute($context, $cartId, $shippingAddresses); return [ 'cart' => [ diff --git a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml index 43941c9740048..f28d484fa0f6f 100644 --- a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml @@ -6,6 +6,15 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <preference for="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface" + type="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCart" /> + <type name="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface"> + <arguments> + <argument name="shippingAddressProcessors" xsi:type="array"> + <item name="singleShippingAddress" xsi:type="object">Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCart\SingleShippingAddressProcessor</item> + </argument> + </arguments> + </type> <virtualType name="multishippingPaymentSpecification" type="Magento\Payment\Model\Method\Specification\Composite"> <arguments> <argument name="specifications" xsi:type="array"> From 55b6f4e46809d162e2258e4da760228ec4062a93 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Mon, 5 Nov 2018 22:12:55 +0200 Subject: [PATCH 670/812] graphQl: fixed SetShippingAddressesInterface param --- .../QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php | 5 +++-- .../SingleShippingAddressProcessor.php | 5 +++-- .../Model/Cart/SetShippingAddressesOnCartInterface.php | 5 +++-- .../Model/Resolver/SetShippingAddressesOnCart.php | 3 +-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php index ad3615b94f8ef..8ebcdef1f549a 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php @@ -9,6 +9,7 @@ use InvalidArgumentException; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Quote\Api\Data\CartInterface; /** * Set shipping addresses for shopping cart processors chain @@ -32,7 +33,7 @@ public function __construct( /** * @inheritdoc */ - public function execute(ContextInterface $context, int $cartId, array $shippingAddresses): void + public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void { foreach ($this->shippingAddressProcessors as $shippingAddressProcessor) { if (!$shippingAddressProcessor instanceof SetShippingAddressesOnCartInterface) { @@ -42,7 +43,7 @@ public function execute(ContextInterface $context, int $cartId, array $shippingA ); } - $shippingAddressProcessor->execute($context, $cartId, $shippingAddresses); + $shippingAddressProcessor->execute($context, $cart, $shippingAddresses); } } } diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php index 6584b9887bed5..41675716c68bf 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php @@ -12,6 +12,7 @@ use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Quote\Api\Data\CartInterface; use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\Customer\Api\AddressRepositoryInterface; @@ -55,7 +56,7 @@ public function __construct( /** * @inheritdoc */ - public function execute(ContextInterface $context, int $cartId, array $shippingAddresses): void + public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void { if (count($shippingAddresses) > 1) { return; @@ -89,6 +90,6 @@ public function execute(ContextInterface $context, int $cartId, array $shippingA $shippingAddress = $this->addressModel->addData($addressInput); } - $this->shippingAddressManagement->assign($cartId, $shippingAddress); + $this->shippingAddressManagement->assign($cart->getId(), $shippingAddress); } } diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php index f9623e36c5395..ae337240c3a26 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php @@ -9,6 +9,7 @@ use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; +use Magento\Quote\Api\Data\CartInterface; /** * Extension point for setting shipping addresses for a specified shopping cart @@ -22,10 +23,10 @@ interface SetShippingAddressesOnCartInterface * Set shipping addresses for a specified shopping cart * * @param ContextInterface $context - * @param int $cartId + * @param CartInterface $cart * @param array $shippingAddresses * @return void * @throws GraphQlInputException */ - public function execute(ContextInterface $context, int $cartId, array $shippingAddresses): void; + public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void; } diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php index ec151214dbc42..587ebb2b6db1f 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php @@ -87,9 +87,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $maskedCartId = $args['input']['cart_id']; $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId()); - $cartId = (int)$cart->getEntityId(); - $this->setShippingAddressesOnCart->execute($context, $cartId, $shippingAddresses); + $this->setShippingAddressesOnCart->execute($context, $cart, $shippingAddresses); return [ 'cart' => [ From e496e26af5dfbe6d109a48c7f0071cd257bcf7fc Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Mon, 5 Nov 2018 14:32:34 -0600 Subject: [PATCH 671/812] MAGETWO-95589: [FT][Temando] Tests fail with enabled Temando extension --- .../Mftf/ActionGroup/StorefrontProductCartActionGroup.xml | 5 ++++- .../Test/Mftf/Section/CheckoutCartSummarySection.xml | 1 + .../Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml | 3 ++- .../Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml | 3 ++- .../Test/Mftf/Test/StorefrontCartPriceRuleState.xml | 3 ++- .../CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml | 2 ++ .../Test/Block/Adminhtml/Order/Create/Shipping/Method.php | 1 - 7 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml index 4b5b250078ad4..8ef9ff9e8df38 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml @@ -84,7 +84,10 @@ <argument name="total"/> </arguments> <seeInCurrentUrl url="{{CheckoutCartPage.url}}" stepKey="assertUrl"/> - <waitForText userInput="${{total}}" selector="{{CheckoutCartSummarySection.total}}" time="30" stepKey="waitForTotal"/> + <waitForPageLoad stepKey="waitForCartPage"/> + <conditionalClick selector="{{CheckoutCartSummarySection.shippingHeading}}" dependentSelector="{{CheckoutCartSummarySection.shippingMethodForm}}" visible="false" stepKey="openEstimateShippingSection"/> + <waitForElementVisible selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="waitForShippingSection"/> + <checkOption selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="selectShippingMethod"/> <see userInput="${{subtotal}}" selector="{{CheckoutCartSummarySection.subtotal}}" stepKey="assertSubtotal"/> <see userInput="${{shipping}}" selector="{{CheckoutCartSummarySection.shipping}}" stepKey="assertShipping"/> <see userInput="({{shippingMethod}})" selector="{{CheckoutCartSummarySection.shippingMethod}}" stepKey="assertShippingMethod"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml index a1a8d2ba3eade..c2e0868848188 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml @@ -10,6 +10,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="CheckoutCartSummarySection"> <element name="subtotal" type="text" selector="//*[@id='cart-totals']//tr[@class='totals sub']//td//span[@class='price']"/> + <element name="shippingMethodForm" type="text" selector="#co-shipping-method-form"/> <element name="shippingMethod" type="text" selector="//*[@id='cart-totals']//tr[@class='totals shipping excl']//th//span[@class='value']"/> <element name="shipping" type="text" selector="//*[@id='cart-totals']//tr[@class='totals shipping excl']//td//span[@class='price']"/> <element name="total" type="text" selector="//*[@id='cart-totals']//tr[@class='grand totals']//td//span[@class='price']"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml index 3eec020e26347..045fdbb33763f 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountry.xml @@ -72,11 +72,12 @@ <!-- Should not see the discount yet because we have not set country --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> <waitForPageLoad stepKey="waitForCartPage"/> + <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="openEstimateShippingSection"/> + <checkOption selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="selectFlatRateShipping"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> <!-- See discount if we use valid country --> - <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="expandShipping"/> <selectOption selector="{{CheckoutCartSummarySection.country}}" userInput="Brazil" stepKey="fillCountry"/> <waitForPageLoad stepKey="waitForCountry1"/> <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml index 73b5d2546f439..d8c3ef9c32b0b 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcode.xml @@ -76,11 +76,12 @@ <!-- Should not see the discount yet because we have not filled in postcode --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> <waitForPageLoad stepKey="waitForCartPage"/> + <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="openEstimateShippingSection"/> + <checkOption selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="selectFlatRateShipping"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> <!-- See discount if we use valid postcode --> - <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="expandShipping"/> <fillField selector="{{CheckoutCartSummarySection.postcode}}" userInput="78613" stepKey="fillPostcode"/> <waitForPageLoad stepKey="waitForPostcode1"/> <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml index 9395e87c20edb..647f4d6e5c800 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleState.xml @@ -72,11 +72,12 @@ <!-- Should not see the discount yet because we have not filled in postcode --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> <waitForPageLoad stepKey="waitForCartPage"/> + <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="expandShipping"/> + <checkOption selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="selectFlatRateShipping"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> <!-- See discount if we use valid postcode --> - <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="expandShipping"/> <selectOption selector="{{CheckoutCartSummarySection.stateProvince}}" userInput="Indiana" stepKey="fillState"/> <waitForPageLoad stepKey="waitForPostcode1"/> <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml index 1fad2f282fa5d..719e9bb95694e 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml @@ -106,6 +106,8 @@ <data name="productPrice/0/special" xsi:type="string">5</data> <data name="productPrice/0/sub_total" xsi:type="string">5</data> <data name="productPrice/0/regular" xsi:type="string">10</data> + <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data> + <data name="shipping/shipping_method" xsi:type="string">Fixed</data> <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleNotAppliedCatalogPage" /> <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleNotAppliedProductPage" /> <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleNotAppliedShoppingCart" /> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Method.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Method.php index 2ee6269c39d47..a0520e1c7ef8f 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Method.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Method.php @@ -67,7 +67,6 @@ function () { */ private function waitFormLoading() { - $this->_rootElement->click(); $this->browser->waitUntil( function () { return $this->browser->find($this->waitElement)->isVisible() ? null : true; From 8df9f0208f93993a065ace2ee5e32612134898bb Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Tue, 6 Nov 2018 09:30:41 +0200 Subject: [PATCH 672/812] MAGETWO-96007: Customer address issue when creating or updating via API --- .../ResourceModel/CustomerRepositoryTest.php | 63 ++++++++++++------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php index 15afc87405ffd..75dfcf7e8f2fd 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php @@ -294,8 +294,6 @@ public function testUpdateCustomerPreserveAllAddresses() $customerId = 1; $customer = $this->customerRepository->getById($customerId); $customerDetails = $customer->__toArray(); - $defaultBilling = $customerDetails['default_billing']; - $defaultShipping = $customerDetails['default_shipping']; $newCustomerEntity = $this->customerFactory->create(); $this->dataObjectHelper->populateWithArray( $newCustomerEntity, @@ -307,19 +305,8 @@ public function testUpdateCustomerPreserveAllAddresses() $this->customerRepository->save($newCustomerEntity); $newCustomerDetails = $this->customerRepository->getById($customerId); - $newCustomerArray = $newCustomerDetails->__toArray(); //Verify that old addresses are still present $this->assertEquals(2, count($newCustomerDetails->getAddresses())); - $this->assertEquals( - $defaultBilling, - $newCustomerArray['default_billing'], - "Default billing invalid value" - ); - $this->assertEquals( - $defaultShipping, - $newCustomerArray['default_shipping'], - "Default shipping invalid value" - ); } /** @@ -345,19 +332,51 @@ public function testUpdateCustomerDeleteAllAddressesWithEmptyArray() $this->customerRepository->save($newCustomerEntity); $newCustomerDetails = $this->customerRepository->getById($customerId); - $newCustomerArray = $newCustomerDetails->__toArray(); //Verify that old addresses are removed $this->assertEquals(0, count($newCustomerDetails->getAddresses())); - $this->assertEquals( - $newCustomerArray['default_billing'], - null, - "Default billing invalid value" + } + + /** + * Test customer update with new address + * + * @magentoAppArea frontend + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php + */ + public function testUpdateCustomerWithNewAddress() + { + $customerId = 1; + $customer = $this->customerRepository->getById($customerId); + $customerDetails = $customer->__toArray(); + unset($customerDetails['default_billing']); + unset($customerDetails['default_shipping']); + + $beforeSaveCustomer = $this->customerFactory->create(); + $this->dataObjectHelper->populateWithArray( + $beforeSaveCustomer, + $customerDetails, + CustomerInterface::class ); - $this->assertEquals( - $newCustomerArray['default_shipping'], - null, - "Default shipping invalid value" + + $addresses = $customer->getAddresses(); + $beforeSaveAddress = $addresses[0]->__toArray(); + unset($beforeSaveAddress['id']); + $newAddressDataObject = $this->addressFactory->create(); + $this->dataObjectHelper->populateWithArray( + $newAddressDataObject, + $beforeSaveAddress, + AddressInterface::class ); + + $beforeSaveCustomer->setAddresses([$newAddressDataObject]); + $this->customerRepository->save($beforeSaveCustomer); + + $newCustomer = $this->customerRepository->getById($customerId); + $newCustomerAddresses = $newCustomer->getAddresses(); + $addressId = $newCustomerAddresses[0]->getId(); + + $this->assertEquals($newCustomer->getDefaultBilling(), $addressId, "Default billing invalid value"); + $this->assertEquals($newCustomer->getDefaultShipping(), $addressId, "Default shipping invalid value"); } /** From fef5e974e8bdc75926b41f910d2356883367149b Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 6 Nov 2018 11:31:09 +0200 Subject: [PATCH 673/812] magento-engcom/magento2ce#2306: Code style fixes --- .../Model/Import/Uploader.php | 4 ++-- .../Block/Adminhtml/Edit/Tab/Orders.php | 6 +++--- .../Controller/Account/ForgotPassword.php | 4 +++- app/code/Magento/Swatches/Helper/Data.php | 19 +++++++++++++++++++ .../Framework/Cache/Backend/Memcached.php | 9 ++++++--- .../Magento/Framework/Filter/Template.php | 13 +++++++++++-- .../Setup/Module/I18n/Parser/Adapter/Html.php | 2 +- .../Setup/Module/I18n/Parser/Adapter/Js.php | 2 +- 8 files changed, 46 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php index 8dc551c407277..ae4be4a1e62b3 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php @@ -101,7 +101,7 @@ class Uploader extends \Magento\MediaStorage\Model\File\Uploader * @param \Magento\MediaStorage\Model\File\Validator\NotProtectedExtension $validator * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Framework\Filesystem\File\ReadFactory $readFactory - * @param null $filePath + * @param null|string $filePath * @throws \Magento\Framework\Exception\LocalizedException */ public function __construct( @@ -353,7 +353,7 @@ protected function _moveFile($tmpPath, $destPath) } /** - * {@inheritdoc} + * @inheritdoc */ protected function chmod($file) { diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php index 5059d61eb3f7e..f2b8133e352ad 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php @@ -57,7 +57,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ protected function _construct() { @@ -102,7 +102,7 @@ protected function _prepareCollection() } /** - * {@inheritdoc} + * @inheritdoc */ protected function _prepareColumns() { @@ -163,7 +163,7 @@ public function getRowUrl($row) } /** - * {@inheritdoc} + * @inheritdoc */ public function getGridUrl() { diff --git a/app/code/Magento/Customer/Controller/Account/ForgotPassword.php b/app/code/Magento/Customer/Controller/Account/ForgotPassword.php index b94f1993053d4..cfa605580777c 100644 --- a/app/code/Magento/Customer/Controller/Account/ForgotPassword.php +++ b/app/code/Magento/Customer/Controller/Account/ForgotPassword.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -11,6 +10,9 @@ use Magento\Framework\App\Action\Context; use Magento\Framework\View\Result\PageFactory; +/** + * Forgot Password controller + */ class ForgotPassword extends \Magento\Customer\Controller\AbstractAccount implements HttpGetActionInterface { /** diff --git a/app/code/Magento/Swatches/Helper/Data.php b/app/code/Magento/Swatches/Helper/Data.php index ac19ad5116cc3..d82109ac12603 100644 --- a/app/code/Magento/Swatches/Helper/Data.php +++ b/app/code/Magento/Swatches/Helper/Data.php @@ -132,6 +132,8 @@ public function __construct( } /** + * Assemble Additional Data for Eav Attribute + * * @param Attribute $attribute * @return $this */ @@ -181,6 +183,8 @@ private function isMediaAvailable(ModelProduct $product, string $attributeCode): } /** + * Load first variation + * * @param string $attributeCode swatch_image|image * @param ModelProduct $configurableProduct * @param array $requiredAttributes @@ -204,6 +208,8 @@ private function loadFirstVariation($attributeCode, ModelProduct $configurablePr } /** + * Load first variation with swatch image + * * @param Product $configurableProduct * @param array $requiredAttributes * @return bool|Product @@ -214,6 +220,8 @@ public function loadFirstVariationWithSwatchImage(Product $configurableProduct, } /** + * Load first variation with image + * * @param Product $configurableProduct * @param array $requiredAttributes * @return bool|Product @@ -269,6 +277,8 @@ public function loadVariationByFallback(Product $parentProduct, array $attribute } /** + * Add filter by attribute + * * @param ProductCollection $productCollection * @param array $attributes * @return void @@ -281,6 +291,8 @@ private function addFilterByAttributes(ProductCollection $productCollection, arr } /** + * Add filter by parent + * * @param ProductCollection $productCollection * @param integer $parentId * @return void @@ -299,6 +311,7 @@ private function addFilterByParent(ProductCollection $productCollection, $parent /** * Method getting full media gallery for current Product + * * Array structure: [ * ['image'] => 'http://url/pub/media/catalog/product/2/0/blabla.jpg', * ['mediaGallery'] => [ @@ -307,7 +320,9 @@ private function addFilterByParent(ProductCollection $productCollection, $parent * ..., * ] * ] + * * @param ModelProduct $product + * * @return array */ public function getProductMediaGallery(ModelProduct $product) @@ -339,6 +354,8 @@ public function getProductMediaGallery(ModelProduct $product) } /** + * Get all size images + * * @param string $imageFile * @return array */ @@ -476,6 +493,8 @@ private function setCachedSwatches(array $optionIds, array $swatches) } /** + * Add fallback options + * * @param array $fallbackValues * @param array $swatches * @return array diff --git a/lib/internal/Magento/Framework/Cache/Backend/Memcached.php b/lib/internal/Magento/Framework/Cache/Backend/Memcached.php index ff9413aa90fea..0621c63acbd86 100644 --- a/lib/internal/Magento/Framework/Cache/Backend/Memcached.php +++ b/lib/internal/Magento/Framework/Cache/Backend/Memcached.php @@ -5,6 +5,9 @@ */ namespace Magento\Framework\Cache\Backend; +/** + * Memcached cache model + */ class Memcached extends \Zend_Cache_Backend_Memcached implements \Zend_Cache_Backend_ExtendedInterface { /** @@ -46,7 +49,7 @@ public function __construct(array $options = []) * Returns ID of a specific chunk on the basis of data's ID * * @param string $id Main data's ID - * @param int $index Particular chunk number to return ID for + * @param int $index Particular chunk number to return ID for * @return string */ protected function _getChunkId($id, $index) @@ -58,7 +61,7 @@ protected function _getChunkId($id, $index) * Remove saved chunks in case something gone wrong (e.g. some chunk from the chain can not be found) * * @param string $id ID of data's info cell - * @param int $chunks Number of chunks to remove (basically, the number after '{splitted}|') + * @param int $chunks Number of chunks to remove (basically, the number after '{splitted}|') * @return null */ protected function _cleanTheMess($id, $chunks) @@ -103,7 +106,7 @@ public function save($data, $id, $tags = [], $specificLifetime = false) * Load data from memcached, glue from several chunks if it was splitted upon save. * * @param string $id @see \Zend_Cache_Backend_Memcached::load() - * @param bool $doNotTestCacheValidity @see \Zend_Cache_Backend_Memcached::load() + * @param bool $doNotTestCacheValidity @see \Zend_Cache_Backend_Memcached::load() * @return bool|false|string */ public function load($id, $doNotTestCacheValidity = false) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index e0cbab450f6be..3e5f9bcf0bd27 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -10,6 +10,8 @@ namespace Magento\Framework\Filter; /** + * Template filter + * * @api */ class Template implements \Zend_Filter_Interface @@ -228,8 +230,9 @@ protected function afterFilter($value) } /** - * Adds a callback to run after main filtering has happened. Callback must accept a single argument and return - * a string of the processed value. + * Adds a callback to run after main filtering has happened. + * + * Callback must accept a single argument and return a string of the processed value. * * @param callable $afterFilterCallback * @return $this @@ -257,6 +260,8 @@ protected function resetAfterFilterCallbacks() } /** + * Get var directive + * * @param string[] $construction * @return string */ @@ -302,6 +307,8 @@ public function templateDirective($construction) } /** + * Get depend directive + * * @param string[] $construction * @return string */ @@ -320,6 +327,8 @@ public function dependDirective($construction) } /** + * If directive + * * @param string[] $construction * @return string */ diff --git a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php index 6867944d95f8f..cf38fd70884f3 100644 --- a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php +++ b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Html.php @@ -20,7 +20,7 @@ class Html extends AbstractAdapter const HTML_FILTER = "/i18n:\s?'(?<value>[^'\\\\]*(?:\\\\.[^'\\\\]*)*)'/i"; /** - * {@inheritdoc} + * @inheritdoc */ protected function _parse() { diff --git a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php index 6b53a1a4c15b7..4678af60d63f0 100644 --- a/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php +++ b/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Js.php @@ -11,7 +11,7 @@ class Js extends AbstractAdapter { /** - * {@inheritdoc} + * @inheritdoc */ protected function _parse() { From 46e06440229c51f35ff96123b575be4b21fa9f1e Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Tue, 6 Nov 2018 13:40:36 +0300 Subject: [PATCH 674/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 3fb7e9ecc8b4b..88758d63d0148 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -47,6 +47,7 @@ define([ if (~~this.currentPage() === this.pages()) { return false; } + for (index; index < recordData.length; index++) { recordData[index].position = index + offset; } From 0a9977fe2b0810e01dd32557dafaa4a31f2a0e5e Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 6 Nov 2018 13:03:24 +0200 Subject: [PATCH 675/812] GraphQL-174: Absolute image paths for Products --- .../Resolver/Product/ProductImage/Path.php | 45 ------ .../CatalogGraphQl/etc/schema.graphqls | 1 - .../GraphQl/Catalog/ProductImageTest.php | 139 ++++++++++++++++++ 3 files changed, 139 insertions(+), 46 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.php deleted file mode 100644 index 249f1dc40b19a..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Path.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\Product\ProductImage; - -use Magento\Catalog\Model\Product; -use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; - -/** - * Returns product's image path - */ -class Path implements ResolverInterface -{ - /** - * @inheritdoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ) { - if (!isset($value['image_type'])) { - throw new LocalizedException(__('"image_type" value should be specified')); - } - - if (!isset($value['model'])) { - throw new LocalizedException(__('"model" value should be specified')); - } - - /** @var Product $product */ - $product = $value['model']; - - $imagePath = $product->getData($value['image_type']); - return $imagePath; - } -} diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index fb042c7e59c15..5efe37d8f91f6 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -351,7 +351,6 @@ type CustomizableFileValue @doc(description: "CustomizableFileValue defines the type ProductImage @doc(description: "Product image information. Contains image relative path, URL and label") { url: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Url") - path: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Path") label: String @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage\\Label") } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php new file mode 100644 index 0000000000000..dc7c4b1c03040 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php @@ -0,0 +1,139 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Catalog; + +use Magento\TestFramework\TestCase\GraphQlAbstract; + +class ProductImageTest extends GraphQlAbstract +{ + /** + * @var \Magento\TestFramework\ObjectManager + */ + private $objectManager; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php + */ + public function testProductWithBaseImage() + { + $productSku = 'simple'; + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + image { + url + label + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertContains('magento_image.jpg', $response['products']['items'][0]['image']['url']); + self::assertTrue($this->checkImageExists($response['products']['items'][0]['image']['url'])); + self::assertEquals('Image Alt Text', $response['products']['items'][0]['image']['label']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testProductWithoutBaseImage() + { + $this->markTestIncomplete('https://github.com/magento/graphql-ce/issues/239'); + $productSku = 'simple'; + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + image { + url + label + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + self::assertEquals('Simple Product', $response['products']['items'][0]['image']['label']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php + */ + public function testProductWithSmallImage() + { + $productSku = 'simple'; + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + small_image { + url + path + label + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertContains('magento_image.jpg', $response['products']['items'][0]['small_image']['url']); + self::assertTrue($this->checkImageExists($response['products']['items'][0]['small_image']['url'])); + self::assertEquals('Image Alt Text', $response['products']['items'][0]['small_image']['label']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php + */ + public function testProductWithThumbnail() + { + $productSku = 'simple'; + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + thumbnail { + url + path + label + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertContains('magento_image.jpg', $response['products']['items'][0]['thumbnail']['url']); + self::assertTrue($this->checkImageExists($response['products']['items'][0]['thumbnail']['url'])); + self::assertEquals('Image Alt Text', $response['products']['items'][0]['thumbnail']['label']); + } + + /** + * @param string $url + * @return bool + */ + private function checkImageExists(string $url): bool + { + $connection = curl_init($url); + curl_setopt($connection, CURLOPT_HEADER, true); + curl_setopt($connection, CURLOPT_NOBODY, true); + curl_setopt($connection, CURLOPT_RETURNTRANSFER, 1); + curl_exec($connection); + $responseStatus = curl_getinfo($connection, CURLINFO_HTTP_CODE); + + return $responseStatus === 200 ? true : false; + } +} From 10fdcfc6edcc5fafe4f622da11cf4593045e2378 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 6 Nov 2018 13:09:01 +0200 Subject: [PATCH 676/812] GraphQL-174: Absolute image paths for Products --- .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 c9f2e5264b951..791696b2fa29e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -299,8 +299,7 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() description gift_message_available id - image - image_label + image {url, label} meta_description meta_keyword meta_title From 67bc1628a1ee0e5f209fd9876279ece0bbc59fc4 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 6 Nov 2018 13:12:24 +0200 Subject: [PATCH 677/812] magento-engcom/magento2ce#2306: Code style fixes --- app/code/Magento/Customer/Model/Authentication.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Customer/Model/Authentication.php b/app/code/Magento/Customer/Model/Authentication.php index b0729647d7eec..6d228e30b8aa4 100644 --- a/app/code/Magento/Customer/Model/Authentication.php +++ b/app/code/Magento/Customer/Model/Authentication.php @@ -83,7 +83,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function processAuthenticationFailure($customerId) { @@ -120,7 +120,7 @@ public function processAuthenticationFailure($customerId) } /** - * {@inheritdoc} + * @inheritdoc */ public function unlock($customerId) { @@ -152,7 +152,7 @@ protected function getMaxFailures() } /** - * {@inheritdoc} + * @inheritdoc */ public function isLocked($customerId) { @@ -161,7 +161,7 @@ public function isLocked($customerId) } /** - * {@inheritdoc} + * @inheritdoc */ public function authenticate($customerId, $password) { From 3196ebc9ff78c7ec61211ee1e36ffe3865de4561 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 6 Nov 2018 14:19:54 +0200 Subject: [PATCH 678/812] GraphQL-174: Absolute image paths for Products -- Update PAT scenario --- setup/performance-toolkit/benchmark.jmx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx index 8b295c9f5fc46..37e07d1319572 100644 --- a/setup/performance-toolkit/benchmark.jmx +++ b/setup/performance-toolkit/benchmark.jmx @@ -40763,7 +40763,7 @@ vars.put("configurable_sku", "Configurable Product - ${__time(YMD)}-${__threadNu <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(\n filter: {\n price: {gt: \"10\"}\n or: {\n sku:{like:\"%Product%\"}\n name:{like:\"%Configurable Product%\"}\n }\n }\n pageSize: 200\n currentPage: 1\n sort: {\n price: ASC\n name:DESC\n }\n ) {\n total_count\n items {\n attribute_set_id\n country_of_manufacture\n created_at\n description\n gift_message_available\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n \t... on PhysicalProductInterface {\n \tweight\n \t}\n }\n page_info {\n page_size\n current_page\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(\n filter: {\n price: {gt: \"10\"}\n or: {\n sku:{like:\"%Product%\"}\n name:{like:\"%Configurable Product%\"}\n }\n }\n pageSize: 200\n currentPage: 1\n sort: {\n price: ASC\n name:DESC\n }\n ) {\n total_count\n items {\n attribute_set_id\n country_of_manufacture\n created_at\n description\n gift_message_available\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n \t... on PhysicalProductInterface {\n \tweight\n \t}\n }\n page_info {\n page_size\n current_page\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -40820,7 +40820,7 @@ vars.put("configurable_sku", "Configurable Product - ${__time(YMD)}-${__threadNu <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${simple_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${simple_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -40896,7 +40896,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: {eq:\"${configurable_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: {eq:\"${configurable_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -40965,7 +40965,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(\n search: \"configurable\"\n filter: {price: {gteq: \"1\"} }\n ) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(\n search: \"configurable\"\n filter: {price: {gteq: \"1\"} }\n ) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41025,7 +41025,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(search: \"configurable\") {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(search: \"configurable\") {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41085,7 +41085,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(search: \"color\") {\n filters {\n name\n filter_items_count\n request_var\n filter_items {\n label\n value_string\n items_count\n ... on SwatchLayerFilterItemInterface {\n swatch_data {\n type\n value\n }\n }\n }\n }\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n weight\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(search: \"color\") {\n filters {\n name\n filter_items_count\n request_var\n filter_items {\n label\n value_string\n items_count\n ... on SwatchLayerFilterItemInterface {\n swatch_data {\n type\n value\n }\n }\n }\n }\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n weight\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41145,7 +41145,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${bundle_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on BundleProduct {\n weight\n price_view\n dynamic_price\n dynamic_sku\n ship_bundle_items\n dynamic_weight\n items {\n option_id\n title\n required\n type\n position\n sku\n options {\n id\n qty\n position\n is_default\n price\n price_type\n can_change_quantity\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${bundle_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on BundleProduct {\n weight\n price_view\n dynamic_price\n dynamic_sku\n ship_bundle_items\n dynamic_weight\n items {\n option_id\n title\n required\n type\n position\n sku\n options {\n id\n qty\n position\n is_default\n price\n price_type\n can_change_quantity\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41214,7 +41214,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${downloadable_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n ... on DownloadableProduct {\n links_purchased_separately\n links_title\n downloadable_product_samples {\n id\n title\n sort_order\n sample_type\n sample_file\n sample_url\n }\n downloadable_product_links {\n id\n title\n sort_order\n is_shareable\n price\n number_of_downloads\n link_type\n sample_type\n sample_file\n sample_url\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${downloadable_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n ... on DownloadableProduct {\n links_purchased_separately\n links_title\n downloadable_product_samples {\n id\n title\n sort_order\n sample_type\n sample_file\n sample_url\n }\n downloadable_product_links {\n id\n title\n sort_order\n is_shareable\n price\n number_of_downloads\n link_type\n sample_type\n sample_file\n sample_url\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41301,7 +41301,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${virtual_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${virtual_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41368,7 +41368,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${grouped_product_sku}\"} }) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on GroupedProduct {\n weight\n items {\n qty\n position\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n image_label\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n }\n small_image_label\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n thumbnail_label\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${grouped_product_sku}\"} }) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on GroupedProduct {\n weight\n items {\n qty\n position\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> From bfd8feb724a44beeee3945f06fc5946a1529b86d Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Tue, 6 Nov 2018 15:24:28 +0300 Subject: [PATCH 679/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 88758d63d0148..fbd134cdf29d8 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -54,7 +54,6 @@ define([ this.recordData(recordData); }, - /** * Update position for element after position from another page is entered * From c0c1d76192b57fe524d0b9d2672282221ea8b011 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 6 Nov 2018 14:07:03 +0100 Subject: [PATCH 680/812] Added checkout module dependency --- app/code/Magento/QuoteGraphQl/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index c9900dd5f3150..f0d2eea9bcaf6 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -6,6 +6,7 @@ "php": "~7.1.3||~7.2.0", "magento/framework": "*", "magento/module-quote": "*", + "magento/module-checkout": "*", "magento/module-catalog": "*", "magento/module-store": "*" }, From 591168ed6ab3e62a374f5c32bc4e5fb8a406740e Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Tue, 6 Nov 2018 15:52:45 +0200 Subject: [PATCH 681/812] ENGCOM-3358: [Forwardport] Prevent rendering of 'Ship here' button to select a shipping item if it is already selected #18986 Fix function test. --- .../Test/Mftf/Section/CheckoutShippingMethodsSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml index ceb4505c79693..56ed42fbfbbea 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml @@ -14,7 +14,7 @@ <element name="shippingMethodRow" type="text" selector=".form.methods-shipping table tbody tr"/> <element name="checkShippingMethodByName" type="radio" selector="//div[@id='checkout-shipping-method-load']//td[contains(., '{{var1}}')]/..//input" parameterized="true"/> <element name="shippingMethodRowByName" type="text" selector="//div[@id='checkout-shipping-method-load']//td[contains(., '{{var1}}')]/.." parameterized="true"/> - <element name="shipHereButton" type="button" selector="//button[contains(@class, 'action-select-shipping-item')]/parent::div/following-sibling::div/button[contains(@class, 'action-select-shipping-item')]"/> + <element name="shipHereButton" type="button" selector="//div/following-sibling::div/button[contains(@class, 'action-select-shipping-item')]"/> <element name="shippingMethodLoader" type="button" selector="//div[contains(@class, 'checkout-shipping-method')]/following-sibling::div[contains(@class, 'loading-mask')]"/> </section> </sections> From c3b4a8078771dd6ba76b1d00d9709a37b81c7677 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 6 Nov 2018 15:00:00 +0100 Subject: [PATCH 682/812] Covered most cases except authorisation --- .../Quote/SetShippingMethodOnCartTest.php | 160 +++++++++++++++--- 1 file changed, 132 insertions(+), 28 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php index 64c7cbf9fd42e..932c8ac386c27 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php @@ -39,6 +39,9 @@ class SetShippingMethodOnCartTest extends GraphQlAbstract */ private $quoteIdToMaskedId; + /** + * @inheritdoc + */ protected function setUp() { $objectManager = Bootstrap::getObjectManager(); @@ -51,26 +54,139 @@ protected function setUp() /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php */ - public function testSetShippingOnCart() + public function testSetShippingMethodOnCart() { + $shippingCarrierCode = 'flatrate'; + $shippingMethodCode = 'flatrate'; $this->quoteResource->load( $this->quote, 'test_order_1', 'reserved_order_id' ); + $shippingAddress = $this->quote->getShippingAddress(); + $shippingAddressId = $shippingAddress->getId(); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $shippingMethodCode, + $shippingCarrierCode, + $shippingAddressId + ); + + $response = $this->sendRequestWithToken($query); + + self::assertArrayHasKey('setShippingMethodsOnCart', $response); + self::assertArrayHasKey('cart', $response['setShippingMethodsOnCart']); + self::assertEquals($maskedQuoteId, $response['setShippingMethodsOnCart']['cart']['cart_id']); + $addressesInformation = $response['setShippingMethodsOnCart']['cart']['addresses']; + self::assertCount(2, $addressesInformation); + self::assertEquals( + $addressesInformation[0]['selected_shipping_method']['code'], + $shippingCarrierCode . '_' . $shippingMethodCode + ); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetShippingMethodWithWrongCartId() + { + $shippingCarrierCode = 'flatrate'; + $shippingMethodCode = 'flatrate'; + $shippingAddressId = '1'; + $maskedQuoteId = 'invalid'; + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $shippingMethodCode, + $shippingCarrierCode, + $shippingAddressId + ); + + self::expectExceptionMessage("Could not find a cart with ID \"$maskedQuoteId\""); + $this->sendRequestWithToken($query); + } + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetNonExistingShippingMethod() + { + $shippingCarrierCode = 'non'; + $shippingMethodCode = 'existing'; + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); $shippingAddress = $this->quote->getShippingAddress(); $shippingAddressId = $shippingAddress->getId(); $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); - $query = <<<QUERY + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $shippingMethodCode, + $shippingCarrierCode, + $shippingAddressId + ); + + self::expectExceptionMessage("Carrier with such method not found: $shippingCarrierCode, $shippingMethodCode"); + $this->sendRequestWithToken($query); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetShippingMethodWithNonExistingAddress() + { + $shippingCarrierCode = 'flatrate'; + $shippingMethodCode = 'flatrate'; + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $shippingAddressId = '-20'; + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $shippingMethodCode, + $shippingCarrierCode, + $shippingAddressId + ); + + self::expectExceptionMessage('The shipping address is missing. Set the address and try again.'); + $this->sendRequestWithToken($query); + } + + // TODO: TBD - add check for guest with attempt to set shipping method to the customer's shopping cart + + /** + * Generates query for setting the specified shipping method on cart + * + * @param string $maskedQuoteId + * @param string $shippingMethodCode + * @param string $shippingCarrierCode + * @param string $shippingAddressId + * @return string + */ + private function prepareMutationQuery( + string $maskedQuoteId, + string $shippingMethodCode, + string $shippingCarrierCode, + string $shippingAddressId + ) : string { + return <<<QUERY mutation { setShippingMethodsOnCart(input: { cart_id: "$maskedQuoteId", shipping_methods: [ { - shipping_method_code: "flatrate" - shipping_carrier_code: "flatrate" + shipping_method_code: "$shippingMethodCode" + shipping_carrier_code: "$shippingCarrierCode" cart_address_id: $shippingAddressId } ]}) { @@ -78,22 +194,6 @@ public function testSetShippingOnCart() cart { cart_id, addresses { - firstname - lastname - company - address_type - city - street - region { - code - label - } - postcode - country { - code - label - } - selected_shipping_method { code label @@ -104,17 +204,21 @@ public function testSetShippingOnCart() } QUERY; + } + + /** + * Sends a GraphQL request with using a bearer token + * + * @param string $query + * @return array + * @throws \Magento\Framework\Exception\AuthenticationException + */ + private function sendRequestWithToken(string $query): array + { $customerToken = $this->customerTokenService->createCustomerAccessToken('customer@example.com', 'password'); $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; - $response = $this->graphQlQuery($query, [], '', $headerMap); - - self::assertArrayHasKey('setShippingMethodsOnCart', $response); - self::assertArrayHasKey('cart', $response['setShippingMethodsOnCart']); - self::assertEquals($maskedQuoteId, $response['setShippingMethodsOnCart']['cart']['cart_id']); - // TODO: check shipping method code and description + return $this->graphQlQuery($query, [], '', $headerMap); } - - // TODO: cover all other cases } From ddb64a537e44cf54490485fa79c5873d6865551e Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 6 Nov 2018 16:03:34 +0200 Subject: [PATCH 683/812] GraphQL-174: Absolute image paths for Products -- Fix static tests --- .../Model/Resolver/Product/ProductImage/Label.php | 2 ++ .../CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php index e9020c2df5333..f971e35742628 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Label.php @@ -80,6 +80,8 @@ public function resolve( } /** + * Get attribute value + * * @param int $productId * @param string $attributeCode * @return null|string Null if attribute value is not exists diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php index c6659080ee9e9..3c19ce599a9b3 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductImage/Url.php @@ -60,6 +60,8 @@ public function resolve( } /** + * Get image url + * * @param string $imageType * @param string|null $imagePath Null if image is not set * @return string From 32baeb40f1fdc3842bfa2c8c8b95a7c74ddf8ed5 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 6 Nov 2018 16:26:50 +0200 Subject: [PATCH 684/812] GraphQL-174: Absolute image paths for Products -- Fix API-functional tests --- .../testsuite/Magento/GraphQl/Catalog/CategoryTest.php | 7 +++---- .../testsuite/Magento/GraphQl/Catalog/ProductImageTest.php | 2 -- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php index cc91ba7ed399d..a3c6298c70a53 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php @@ -141,8 +141,7 @@ public function testCategoryProducts() available_sort_by level } - image { url, path, label } - image_label + image { url, label } meta_description meta_keyword meta_title @@ -225,8 +224,8 @@ public function testCategoryProducts() } short_description sku - small_image { url, path, label } - thumbnail { url, path, label } + small_image { url, label } + thumbnail { url, label } special_from_date special_price special_to_date diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php index dc7c4b1c03040..b55c6c1d91460 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php @@ -81,7 +81,6 @@ public function testProductWithSmallImage() items { small_image { url - path label } } @@ -107,7 +106,6 @@ public function testProductWithThumbnail() items { thumbnail { url - path label } } From 5934b231fe89fde967936124f714b929f2a1aada Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Tue, 6 Nov 2018 17:38:53 +0300 Subject: [PATCH 685/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../adminhtml/web/js/grouped-product-grid.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index fbd134cdf29d8..9cb0a00dc9521 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -57,8 +57,8 @@ define([ /** * Update position for element after position from another page is entered * - * @param data - * @param event + * @param {Object} data + * @param {Object} event */ updateGridPosition: function (data, event) { var inputValue = parseInt(event.target.value, 10), @@ -102,8 +102,8 @@ define([ /** * Get updated record index * - * @param recordData - * @param recordId + * @param {Array} recordData + * @param {Number} recordId * @return {number} */ getUpdatedRecordIndex: function (recordData, recordId) { @@ -114,7 +114,7 @@ define([ /** * - * @param recordData to reprocess + * @param {Array} recordData to reprocess */ reloadGridData: function (recordData) { this.recordData(recordData.sort(function (a, b) { @@ -127,7 +127,7 @@ define([ /** * Event handler for "Send to bottom" button * - * @param positionObj + * @param {Object} positionObj * @return {boolean} */ sendToBottom: function (positionObj) { @@ -151,7 +151,7 @@ define([ /** * Event handler for "Send to top" button * - * @param positionObj + * @param {Object} positionObj * @returns {boolean} */ sendToTop: function (positionObj) { @@ -176,7 +176,7 @@ define([ /** * Get element from grid for update * - * @param object + * @param {Object} object * @return {*} */ getObjectToUpdate: function (object) { @@ -188,7 +188,7 @@ define([ /** * Value function for position input * - * @param data + * @param {Object} data * @return {number} */ getCalculatedPosition: function (data) { From bf5ad21fc451c17b496f5a24280600e5c66c1aba Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Tue, 6 Nov 2018 18:36:03 +0300 Subject: [PATCH 686/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../view/adminhtml/web/js/grouped-product-grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 9cb0a00dc9521..c06f615ae48e6 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -104,7 +104,7 @@ define([ * * @param {Array} recordData * @param {Number} recordId - * @return {number} + * @return {Number} */ getUpdatedRecordIndex: function (recordData, recordId) { return recordData.map(function (o) { From 418d0cabbe129eb0fcc9cf793213de7217292be8 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 6 Nov 2018 11:18:38 -0600 Subject: [PATCH 687/812] MAGETWO-95745: Signifyd case not created for WorldPay --- app/code/Magento/Checkout/Controller/Onepage/Success.php | 5 ++++- app/code/Magento/Signifyd/etc/events.xml | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Controller/Onepage/Success.php b/app/code/Magento/Checkout/Controller/Onepage/Success.php index 7db5cd8f012c7..e0872b425cc7c 100644 --- a/app/code/Magento/Checkout/Controller/Onepage/Success.php +++ b/app/code/Magento/Checkout/Controller/Onepage/Success.php @@ -26,7 +26,10 @@ public function execute() $resultPage = $this->resultPageFactory->create(); $this->_eventManager->dispatch( 'checkout_onepage_controller_success_action', - ['order_ids' => [$session->getLastOrderId()]] + [ + 'order_ids' => [$session->getLastOrderId()], + 'order' => $session->getLastRealOrder() + ] ); return $resultPage; } diff --git a/app/code/Magento/Signifyd/etc/events.xml b/app/code/Magento/Signifyd/etc/events.xml index d5ba6e5a99227..e6418e2fdb6b4 100644 --- a/app/code/Magento/Signifyd/etc/events.xml +++ b/app/code/Magento/Signifyd/etc/events.xml @@ -15,4 +15,7 @@ <event name="paypal_checkout_success"> <observer name="signifyd_place_order_checkout_success_observer" instance="Magento\Signifyd\Observer\PlaceOrder" /> </event> + <event name="checkout_onepage_controller_success_action"> + <observer name="signifyd_place_order_checkout_success_observer" instance="Magento\Signifyd\Observer\PlaceOrder" /> + </event> </config> From 25fd4670c9988c7fe7b365f077f25dfa6d01839a Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 6 Nov 2018 19:19:55 +0200 Subject: [PATCH 688/812] GraphQl-45: Product textarea field format --- .../Product/ProductComplexTextAttribute.php | 2 +- .../Resolver/ComplexTextValue/HtmlFormat.php | 38 ----- app/code/Magento/GraphQl/etc/schema.graphqls | 2 +- .../Magento/GraphQl/Catalog/CategoryTest.php | 8 +- .../Catalog/ProductTextAttributesTest.php | 142 ++++++++++++++++++ .../GraphQl/Catalog/ProductViewTest.php | 34 ----- .../ProductWithDescriptionDirectivesTest.php | 65 -------- 7 files changed, 150 insertions(+), 141 deletions(-) delete mode 100644 app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductTextAttributesTest.php delete mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php index 7cf7225d0f61c..96519d6191eee 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php @@ -52,6 +52,6 @@ public function resolve( $fieldName = $field->getName(); $renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName); - return ['html' => $renderedValue]; + return ['html' => $renderedValue ?? '']; } } diff --git a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php b/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.php deleted file mode 100644 index fffca765faba6..0000000000000 --- a/app/code/Magento/GraphQl/Model/Resolver/ComplexTextValue/HtmlFormat.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\GraphQl\Model\Resolver\ComplexTextValue; - -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; - -/** - * HTML format for complex text value. - * - * Initially, a value from parent resolver should be in HTML format, therefore, there is no any customization. - */ -class HtmlFormat implements ResolverInterface -{ - /** - * @inheritdoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ): ?string { - if (!isset($value['html'])) { - throw new GraphQlInputException(__('"html" value should be specified')); - } - - return $value['html']; - } -} diff --git a/app/code/Magento/GraphQl/etc/schema.graphqls b/app/code/Magento/GraphQl/etc/schema.graphqls index 991c320860622..2281495d059e1 100644 --- a/app/code/Magento/GraphQl/etc/schema.graphqls +++ b/app/code/Magento/GraphQl/etc/schema.graphqls @@ -38,5 +38,5 @@ enum SortEnum @doc(description: "This enumeration indicates whether to return re } type ComplexTextValue { - html: String! @doc(description: "HTML format") @resolver(class: "\\Magento\\GraphQl\\Model\\Resolver\\ComplexTextValue\\HtmlFormat") + html: String! @doc(description: "HTML format") } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php index eff2e96f4b112..adc3a58e4f8dc 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php @@ -132,7 +132,9 @@ public function testCategoryProducts() attribute_set_id country_of_manufacture created_at - description + description { + html + } gift_message_available id categories { @@ -223,7 +225,9 @@ public function testCategoryProducts() position sku } - short_description + short_description { + html + } sku small_image { path diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductTextAttributesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductTextAttributesTest.php new file mode 100644 index 0000000000000..999e1cc7fca3d --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductTextAttributesTest.php @@ -0,0 +1,142 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Catalog; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQlAbstract; + +class ProductTextAttributesTest extends GraphQlAbstract +{ + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + protected function setUp() + { + $this->productRepository = Bootstrap::getObjectManager()::getInstance()->get(ProductRepositoryInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testProductTextAttributes() + { + $productSku = 'simple'; + + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) + { + items { + sku + description { + html + } + short_description { + html + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + $this->assertEquals( + $productSku, + $response['products']['items'][0]['sku'] + ); + $this->assertEquals( + 'Short description', + $response['products']['items'][0]['short_description']['html'] + ); + $this->assertEquals( + 'Description with <b>html tag</b>', + $response['products']['items'][0]['description']['html'] + ); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_virtual.php + */ + public function testProductWithoutFilledTextAttributes() + { + $productSku = 'virtual-product'; + + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) + { + items { + sku + description { + html + } + short_description { + html + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + $this->assertEquals( + $productSku, + $response['products']['items'][0]['sku'] + ); + $this->assertEquals( + '', + $response['products']['items'][0]['short_description']['html'] + ); + $this->assertEquals( + '', + $response['products']['items'][0]['description']['html'] + ); + } + + /** + * Test for checking that product fields with directives allowed are rendered correctly + * + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + * @magentoApiDataFixture Magento/Cms/_files/block.php + */ + public function testHtmlDirectivesRendering() + { + $productSku = 'simple'; + $cmsBlockId = 'fixture_block'; + $assertionCmsBlockText = 'Fixture Block Title'; + + $product = $this->productRepository->get($productSku, false, null, true); + $product->setDescription('Test: {{block id="' . $cmsBlockId . '"}}'); + $product->setShortDescription('Test: {{block id="' . $cmsBlockId . '"}}'); + $this->productRepository->save($product); + + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + description { + html + } + short_description { + html + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['description']['html']); + self::assertNotContains('{{block id', $response['products']['items'][0]['description']['html']); + self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['short_description']['html']); + self::assertNotContains('{{block id', $response['products']['items'][0]['short_description']['html']); + } +} 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 0ec63374be869..a3d0bb28da14a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -44,9 +44,6 @@ public function testQueryAllFieldsSimpleProduct() attribute_set_id country_of_manufacture created_at - description { - html - } gift_message_available id categories { @@ -205,9 +202,6 @@ public function testQueryAllFieldsSimpleProduct() position sku } - short_description { - html - } sku small_image { path @@ -266,7 +260,6 @@ public function testQueryAllFieldsSimpleProduct() $this->assertArrayHasKey(0, $response['products']['items']); $this->assertBaseFields($product, $response['products']['items'][0]); $this->assertEavAttributes($product, $response['products']['items'][0]); - $this->assertComplexTextAttributes($product, $response['products']['items'][0]); $this->assertOptions($product, $response['products']['items'][0]); $this->assertTierPrices($product, $response['products']['items'][0]); $this->assertArrayHasKey('websites', $response['products']['items'][0]); @@ -306,7 +299,6 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() } country_of_manufacture created_at - description gift_message_available id image @@ -457,7 +449,6 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() position sku } - short_description sku small_image { path @@ -947,31 +938,6 @@ private function assertEavAttributes($product, $actualResponse) $this->assertResponseFields($actualResponse, $assertionMap); } - /** - * @param ProductInterface $product - * @param array $actualResponse - */ - private function assertComplexTextAttributes($product, $actualResponse) - { - $eavAttributes = [ - 'description', - 'short_description', - ]; - $assertionMap = []; - foreach ($eavAttributes as $attributeCode) { - $expectedAttribute = $product->getCustomAttribute($attributeCode); - - $assertionMap[] = [ - 'response_field' => $this->eavAttributesToGraphQlSchemaFieldTranslator($attributeCode), - 'expected_value' => $expectedAttribute ? [ - 'html' => $expectedAttribute->getValue() - ] : null - ]; - } - - $this->assertResponseFields($actualResponse, $assertionMap); - } - /** * @param string $eavAttributeCode * @return string diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php deleted file mode 100644 index 8e9bc4dfa2825..0000000000000 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\GraphQl\Catalog; - -use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\TestFramework\ObjectManager; -use Magento\TestFramework\TestCase\GraphQlAbstract; - -/** - * Test for checking that product fields with directives allowed are rendered correctly - */ -class ProductWithDescriptionDirectivesTest extends GraphQlAbstract -{ - /** - * @var \Magento\TestFramework\ObjectManager - */ - private $objectManager; - - protected function setUp() - { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - } - - /** - * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php - * @magentoApiDataFixture Magento/Cms/_files/block.php - */ - public function testHtmlDirectivesRendered() - { - $productSku = 'simple'; - $cmsBlockId = 'fixture_block'; - $assertionCmsBlockText = 'Fixture Block Title'; - - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class); - /** @var ProductInterface $product */ - $product = $productRepository->get($productSku, false, null, true); - $product->setDescription('Test: {{block id="' . $cmsBlockId . '"}}'); - $product->setShortDescription('Test: {{block id="' . $cmsBlockId . '"}}'); - $productRepository->save($product); - - $query = <<<QUERY -{ - products(filter: {sku: {eq: "{$productSku}"}}) { - items { - description - short_description - } - } -} -QUERY; - $response = $this->graphQlQuery($query); - - self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['description']); - self::assertNotContains('{{block id', $response['products']['items'][0]['description']); - self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['short_description']); - self::assertNotContains('{{block id', $response['products']['items'][0]['short_description']); - } -} From 7c21b3b31e5f330e698d6a766cb45e90cf61a3f3 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Tue, 6 Nov 2018 20:36:45 +0200 Subject: [PATCH 689/812] graphQl: removed set shipping addresses chain, using di preference instead --- ...essor.php => SetShippingAddressOnCart.php} | 9 ++-- .../Model/Cart/SetShippingAddressesOnCart.php | 49 ------------------- app/code/Magento/QuoteGraphQl/composer.json | 4 +- .../Magento/QuoteGraphQl/etc/graphql/di.xml | 9 +--- .../Quote/SetShippingAddressOnCartTest.php | 46 +++++++++++++++++ 5 files changed, 55 insertions(+), 62 deletions(-) rename app/code/Magento/QuoteGraphQl/Model/Cart/{SetShippingAddressesOnCart/SingleShippingAddressProcessor.php => SetShippingAddressOnCart.php} (92%) delete mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php similarity index 92% rename from app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php rename to app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php index 41675716c68bf..588d4f65cc565 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart/SingleShippingAddressProcessor.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCart; +namespace Magento\QuoteGraphQl\Model\Cart; use Magento\Authorization\Model\UserContextInterface; use Magento\Customer\Api\Data\AddressInterface; @@ -16,12 +16,11 @@ use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\Customer\Api\AddressRepositoryInterface; -use Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface; /** * Set single shipping address for a specified shopping cart */ -class SingleShippingAddressProcessor implements SetShippingAddressesOnCartInterface +class SetShippingAddressOnCart implements SetShippingAddressesOnCartInterface { /** * @var ShippingAddressManagementInterface @@ -59,7 +58,9 @@ public function __construct( public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void { if (count($shippingAddresses) > 1) { - return; + throw new GraphQlInputException( + __('Multiple addresses do not allowed here!') + ); } $shippingAddress = current($shippingAddresses); $customerAddressId = $shippingAddress['customer_address_id'] ?? null; diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php deleted file mode 100644 index 8ebcdef1f549a..0000000000000 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\QuoteGraphQl\Model\Cart; - -use InvalidArgumentException; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Quote\Api\Data\CartInterface; - -/** - * Set shipping addresses for shopping cart processors chain - */ -class SetShippingAddressesOnCart implements SetShippingAddressesOnCartInterface -{ - /** - * @var SetShippingAddressesOnCartInterface[] - */ - private $shippingAddressProcessors; - - /** - * @param array $shippingAddressProcessors - */ - public function __construct( - array $shippingAddressProcessors - ) { - $this->shippingAddressProcessors = $shippingAddressProcessors; - } - - /** - * @inheritdoc - */ - public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void - { - foreach ($this->shippingAddressProcessors as $shippingAddressProcessor) { - if (!$shippingAddressProcessor instanceof SetShippingAddressesOnCartInterface) { - throw new InvalidArgumentException( - get_class($shippingAddressProcessor) . - ' is not instance of \Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface.' - ); - } - - $shippingAddressProcessor->execute($context, $cart, $shippingAddresses); - } - } -} diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 485c958718bf3..b3433fdc8fea6 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -8,7 +8,9 @@ "magento/module-quote": "*", "magento/module-catalog": "*", "magento/module-store": "*", - "magento/module-checkout": "*" + "magento/module-checkout": "*", + "magento/module-customer": "*", + "magento/module-authorization": "*" }, "suggest": { "magento/module-graph-ql": "*" diff --git a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml index f28d484fa0f6f..e7417d657a0ea 100644 --- a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml @@ -7,14 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface" - type="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCart" /> - <type name="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface"> - <arguments> - <argument name="shippingAddressProcessors" xsi:type="array"> - <item name="singleShippingAddress" xsi:type="object">Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCart\SingleShippingAddressProcessor</item> - </argument> - </arguments> - </type> + type="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressOnCart" /> <virtualType name="multishippingPaymentSpecification" type="Magento\Payment\Model\Method\Specification\Composite"> <arguments> <argument name="specifications" xsi:type="array"> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php index 9771dbbf84c48..48ef8ebb790d1 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php @@ -143,6 +143,52 @@ public function testSetSavedShippingAddressOnCartByGuest() $this->graphQlQuery($query); } + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @magentoConfigFixture default_store multishipping/options/checkout_multiple 0 + */ + public function testSetMultipleShippingAddressesOnCartByGuest() + { + $this->quoteResource->load( + $this->quote, + 'test_order_with_simple_product_without_address', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + customer_address_id: 1 + }, + { + customer_address_id: 1 + } + ] + } + ) { + cart { + addresses { + firstname + lastname + company + street + city + postcode + telephone + } + } + } +} +QUERY; + self::expectExceptionMessage('Multiple addresses do not allowed here!'); + $this->graphQlQuery($query); + } + /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php */ From c8578575c498690cd672764c374ddafec18dcc90 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Tue, 6 Nov 2018 20:38:08 +0200 Subject: [PATCH 690/812] graphQl: fixed composer json --- app/code/Magento/QuoteGraphQl/composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 05575ef371600..9d29cda3b872b 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -9,7 +9,6 @@ "magento/module-checkout": "*", "magento/module-catalog": "*", "magento/module-store": "*", - "magento/module-checkout": "*", "magento/module-customer": "*", "magento/module-authorization": "*" }, From 2095d836b5fc31dac949b37dad31fd6973fea406 Mon Sep 17 00:00:00 2001 From: Dmytro Salamatov <sal.dima27@gmail.com> Date: Tue, 6 Nov 2018 00:11:18 +0200 Subject: [PATCH 691/812] magento/magento2#19071: Password strength indicator shows No Password even when a password is entered --- .../view/frontend/web/js/password-strength-indicator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/view/frontend/web/js/password-strength-indicator.js b/app/code/Magento/Customer/view/frontend/web/js/password-strength-indicator.js index 89d9b320c049d..9742e37f2df57 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/password-strength-indicator.js +++ b/app/code/Magento/Customer/view/frontend/web/js/password-strength-indicator.js @@ -83,7 +83,7 @@ define([ } else { isValid = $.validator.validateSingleElement(this.options.cache.input); zxcvbnScore = zxcvbn(password).score; - displayScore = isValid ? zxcvbnScore : 1; + displayScore = isValid && zxcvbnScore > 0 ? zxcvbnScore : 1; } } From 8aafa54f3356a8d361231cf3d84e19f80ef076c0 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Tue, 6 Nov 2018 14:41:16 -0600 Subject: [PATCH 692/812] ENGCOM-3368: fixed - can't import external http to https redirecting images by default csv import #18900 - Fixed docblock --- lib/internal/Magento/Framework/Filesystem/Driver/Http.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php index e43f35b072f1d..3668bd17477a4 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php @@ -12,7 +12,6 @@ /** * Class Http - * */ class Http extends File { From a58147333b285ed746a9b516d9bc6561c289010d Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Tue, 6 Nov 2018 15:15:52 -0600 Subject: [PATCH 693/812] MQE-1339: Bump MFTF version in Magento - MFTF version upgrade to 2.3.10 --- composer.json | 2 +- composer.lock | 168 +++++++++++++++++++++++++------------------------- 2 files changed, 85 insertions(+), 85 deletions(-) diff --git a/composer.json b/composer.json index ca345c1897412..0a2716489d6c9 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.13.0", "lusitanian/oauth": "~0.8.10", - "magento/magento2-functional-testing-framework": "2.3.9", + "magento/magento2-functional-testing-framework": "2.3.10", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index c6d14eb38bc64..ab0c8f2bf8973 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "49fe82043cd4ae944939b6cceade1d1b", + "content-hash": "52b81b57603c71ff946453178068a064", "packages": [ { "name": "braintree/braintree_php", @@ -257,16 +257,16 @@ }, { "name": "composer/composer", - "version": "1.7.2", + "version": "1.7.3", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "576aab9b5abb2ed11a1c52353a759363216a4ad2" + "reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/576aab9b5abb2ed11a1c52353a759363216a4ad2", - "reference": "576aab9b5abb2ed11a1c52353a759363216a4ad2", + "url": "https://api.github.com/repos/composer/composer/zipball/e965b9aaa8854c3067f1ed2ae45f436572d73eb7", + "reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7", "shasum": "" }, "require": { @@ -333,7 +333,7 @@ "dependency", "package" ], - "time": "2018-08-16T14:57:12+00:00" + "time": "2018-11-01T09:05:06+00:00" }, { "name": "composer/semver", @@ -399,16 +399,16 @@ }, { "name": "composer/spdx-licenses", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b" + "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/cb17687e9f936acd7e7245ad3890f953770dec1b", - "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7a9556b22bd9d4df7cad89876b00af58ef20d3a2", + "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2", "shasum": "" }, "require": { @@ -456,7 +456,7 @@ "spdx", "validator" ], - "time": "2018-04-30T10:33:04+00:00" + "time": "2018-11-01T09:45:54+00:00" }, { "name": "composer/xdebug-handler", @@ -919,16 +919,16 @@ }, { "name": "monolog/monolog", - "version": "1.23.0", + "version": "1.24.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" + "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", - "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", + "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", "shasum": "" }, "require": { @@ -993,7 +993,7 @@ "logging", "psr-3" ], - "time": "2017-06-19T01:22:40+00:00" + "time": "2018-11-05T09:00:11+00:00" }, { "name": "oyejorge/less.php", @@ -1375,16 +1375,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.11", + "version": "2.0.12", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "7053f06f91b3de78e143d430e55a8f7889efc08b" + "reference": "8814dc7841db159daed0b32c2b08fb7e03c6afe7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7053f06f91b3de78e143d430e55a8f7889efc08b", - "reference": "7053f06f91b3de78e143d430e55a8f7889efc08b", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/8814dc7841db159daed0b32c2b08fb7e03c6afe7", + "reference": "8814dc7841db159daed0b32c2b08fb7e03c6afe7", "shasum": "" }, "require": { @@ -1463,7 +1463,7 @@ "x.509", "x509" ], - "time": "2018-04-15T16:55:05+00:00" + "time": "2018-11-04T05:45:48+00:00" }, { "name": "psr/container", @@ -1834,16 +1834,16 @@ }, { "name": "symfony/console", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b" + "reference": "432122af37d8cd52fba1b294b11976e0d20df595" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/dc7122fe5f6113cfaba3b3de575d31112c9aa60b", - "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b", + "url": "https://api.github.com/repos/symfony/console/zipball/432122af37d8cd52fba1b294b11976e0d20df595", + "reference": "432122af37d8cd52fba1b294b11976e0d20df595", "shasum": "" }, "require": { @@ -1898,20 +1898,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-10-03T08:15:46+00:00" + "time": "2018-10-31T09:30:44+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e" + "reference": "552541dad078c85d9414b09c041ede488b456cd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e", - "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/552541dad078c85d9414b09c041ede488b456cd5", + "reference": "552541dad078c85d9414b09c041ede488b456cd5", "shasum": "" }, "require": { @@ -1961,20 +1961,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-07-26T09:10:45+00:00" + "time": "2018-10-10T13:52:42+00:00" }, { "name": "symfony/filesystem", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "596d12b40624055c300c8b619755b748ca5cf0b5" + "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/596d12b40624055c300c8b619755b748ca5cf0b5", - "reference": "596d12b40624055c300c8b619755b748ca5cf0b5", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/fd7bd6535beb1f0a0a9e3ee960666d0598546981", + "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981", "shasum": "" }, "require": { @@ -2011,11 +2011,11 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-10-02T12:40:59+00:00" + "time": "2018-10-30T13:18:25+00:00" }, { "name": "symfony/finder", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -2064,7 +2064,7 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -2122,16 +2122,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", - "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", "shasum": "" }, "require": { @@ -2177,20 +2177,20 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T13:07:52+00:00" }, { "name": "symfony/process", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529" + "reference": "3e83acef94d979b1de946599ef86b3a352abcdc9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ee33c0322a8fee0855afcc11fff81e6b1011b529", - "reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529", + "url": "https://api.github.com/repos/symfony/process/zipball/3e83acef94d979b1de946599ef86b3a352abcdc9", + "reference": "3e83acef94d979b1de946599ef86b3a352abcdc9", "shasum": "" }, "require": { @@ -2226,7 +2226,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-10-02T12:40:59+00:00" + "time": "2018-10-14T20:48:13+00:00" }, { "name": "tedivm/jshrink", @@ -6351,16 +6351,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.3.9", + "version": "2.3.10", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "9885925ea741d0b0eede35be09a45b62d9ef7c84" + "reference": "7cd80dbf1af405473f1a976c3b75097a0f27725d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/9885925ea741d0b0eede35be09a45b62d9ef7c84", - "reference": "9885925ea741d0b0eede35be09a45b62d9ef7c84", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/7cd80dbf1af405473f1a976c3b75097a0f27725d", + "reference": "7cd80dbf1af405473f1a976c3b75097a0f27725d", "shasum": "" }, "require": { @@ -6418,7 +6418,7 @@ "magento", "testing" ], - "time": "2018-10-28T11:19:53+00:00" + "time": "2018-11-06T20:54:16+00:00" }, { "name": "moontoast/math", @@ -8228,7 +8228,7 @@ }, { "name": "symfony/browser-kit", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", @@ -8285,16 +8285,16 @@ }, { "name": "symfony/config", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96" + "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/b3d4d7b567d7a49e6dfafb6d4760abc921177c96", - "reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96", + "url": "https://api.github.com/repos/symfony/config/zipball/991fec8bbe77367fc8b48ecbaa8a4bd6e905a238", + "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238", "shasum": "" }, "require": { @@ -8344,11 +8344,11 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-09-08T13:24:10+00:00" + "time": "2018-10-31T09:09:42+00:00" }, { "name": "symfony/css-selector", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -8401,16 +8401,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30" + "reference": "e72ee2c23d952e4c368ee98610fa22b79b89b483" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f6b9d893ad28aefd8942dc0469c8397e2216fe30", - "reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e72ee2c23d952e4c368ee98610fa22b79b89b483", + "reference": "e72ee2c23d952e4c368ee98610fa22b79b89b483", "shasum": "" }, "require": { @@ -8468,11 +8468,11 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-10-02T12:40:59+00:00" + "time": "2018-10-31T10:54:16+00:00" }, { "name": "symfony/dom-crawler", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", @@ -8529,16 +8529,16 @@ }, { "name": "symfony/http-foundation", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "d528136617ff24f530e70df9605acc1b788b08d4" + "reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d528136617ff24f530e70df9605acc1b788b08d4", - "reference": "d528136617ff24f530e70df9605acc1b788b08d4", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/82d494c1492b0dd24bbc5c2d963fb02eb44491af", + "reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af", "shasum": "" }, "require": { @@ -8579,11 +8579,11 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2018-10-03T08:48:45+00:00" + "time": "2018-10-31T09:09:42+00:00" }, { "name": "symfony/options-resolver", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", @@ -8637,16 +8637,16 @@ }, { "name": "symfony/polyfill-php70", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934" + "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/1e24b0c4a56d55aaf368763a06c6d1c7d3194934", - "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/6b88000cdd431cd2e940caa2cb569201f3f84224", + "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224", "shasum": "" }, "require": { @@ -8692,20 +8692,20 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T06:26:08+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae" + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/95c50420b0baed23852452a7f0c7b527303ed5ae", - "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", "shasum": "" }, "require": { @@ -8747,11 +8747,11 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T13:07:52+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", @@ -8800,7 +8800,7 @@ }, { "name": "symfony/yaml", - "version": "v3.4.17", + "version": "v3.4.18", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", From dda4f8af9ba60997cb7b78fcd7afe61f988b444b Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 6 Nov 2018 15:56:34 -0600 Subject: [PATCH 694/812] MAGETWO-95659: Fix and Unskip MTF OnePageCheckoutOfflinePaymentMethodsTest - address code review comments --- .../Test/Constraint/AssertCartIsEmpty.php | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php index 22a6136737089..cf05079b0a079 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartIsEmpty.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Checkout\Test\Constraint; @@ -29,8 +30,10 @@ class AssertCartIsEmpty extends AbstractConstraint * @param BrowserInterface $browser * @return void */ - public function processAssert(CheckoutCart $checkoutCart, BrowserInterface $browser) - { + public function processAssert( + CheckoutCart $checkoutCart, + BrowserInterface $browser + ): void { $checkoutCart->open(); $cartEmptyBlock = $checkoutCart->getCartEmptyBlock(); @@ -46,7 +49,7 @@ public function processAssert(CheckoutCart $checkoutCart, BrowserInterface $brow $browser->getUrl(), true, 'Wrong link to main page on empty cart page: expected - ' . $_ENV['app_frontend_url'] - . ', actural - ' . $browser->getUrl() + . ', actual - ' . $browser->getUrl() ); } @@ -63,14 +66,18 @@ public function toString() /** * Asserts that two urls are equal * - * @param string $url1 - * @param string $url2 + * @param string $expectedUrl + * @param string $actualUrl * @param bool $ignoreScheme * @param string $message * @return void */ - private function assertUrlEqual($expectedUrl, $actualUrl, $ignoreScheme = false, $message = '') - { + private function assertUrlEqual( + string $expectedUrl, + string $actualUrl, + bool $ignoreScheme = false, + string $message = '' + ): void { $urlArray1 = parse_url($expectedUrl); $urlArray2 = parse_url($actualUrl); if ($ignoreScheme) { From cf824bcda59d97d2890b64a56a72cbb2f71e89ce Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Wed, 7 Nov 2018 12:33:59 +0400 Subject: [PATCH 695/812] MAGETWO-91658: Wrong Checkout Totals Sort Order in cart - Moved test from CE to EE. --- .../Test/Mftf/Data/CheckoutConfigData.xml | 25 ------ .../Mftf/Metadata/checkout_config-meta.xml | 86 ------------------- .../CheckoutTotalsSortOrderInCartTest.xml | 52 ----------- 3 files changed, 163 deletions(-) delete mode 100644 app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml delete mode 100644 app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml delete mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml b/app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml deleted file mode 100644 index bf2ae28009011..0000000000000 --- a/app/code/Magento/Checkout/Test/Mftf/Data/CheckoutConfigData.xml +++ /dev/null @@ -1,25 +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="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="CheckoutShippingTotalsSortOrder" type="checkout_totals_sort_order"> - <requiredEntity type="shipping">ShippingTotalsSortOrder</requiredEntity> - </entity> - - <entity name="ShippingTotalsSortOrder" type="shipping"> - <data key="value">27</data> - </entity> - - <entity name="DefaultCheckoutTotalsSortOrder" type="default_checkout_totals_sort_order"> - <requiredEntity type="checkoutTotalFlagZero">DefaultTotalFlagZero</requiredEntity> - </entity> - <entity name="DefaultTotalFlagZero" type="checkoutTotalFlagZero"> - <data key="value">0</data> - </entity> -</entities> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml b/app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml deleted file mode 100644 index 55572ee73ac46..0000000000000 --- a/app/code/Magento/Checkout/Test/Mftf/Metadata/checkout_config-meta.xml +++ /dev/null @@ -1,86 +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="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> - <operation name="SetCheckoutTotalsSortOrder" dataType="checkout_totals_sort_order" type="create" auth="adminFormKey" url="/admin/system_config/save/section/sales/" method="POST"> - <object key="groups" dataType="checkout_totals_sort_order"> - <object key="totals_sort" dataType="checkout_totals_sort_order"> - <object key="fields" dataType="checkout_totals_sort_order"> - <object key="subtotal" dataType="subtotal"> - <field key="value">integer</field> - </object> - <object key="discount" dataType="discount"> - <field key="value">integer</field> - </object> - <object key="shipping" dataType="shipping"> - <field key="value">integer</field> - </object> - <object key="tax" dataType="tax"> - <field key="value">integer</field> - </object> - <object key="weee" dataType="weee"> - <field key="value">integer</field> - </object> - <object key="grand_total" dataType="grand_total"> - <field key="value">integer</field> - </object> - <object key="giftcardaccount" dataType="giftcardaccount"> - <field key="value">integer</field> - </object> - <object key="customerbalance" dataType="customerbalance"> - <field key="value">integer</field> - </object> - </object> - </object> - </object> - </operation> - - <operation name="DefaultCheckoutTotalsSortOrder" dataType="default_checkout_totals_sort_order" type="create" auth="adminFormKey" url="/admin/system_config/save/section/sales/" method="POST"> - <object key="groups" dataType="default_checkout_totals_sort_order"> - <object key="totals_sort" dataType="default_checkout_totals_sort_order"> - <object key="fields" dataType="default_checkout_totals_sort_order"> - <object key="subtotal" dataType="default_checkout_totals_sort_order"> - <object key="inherit" dataType="checkoutTotalFlagZero"> - <field key="value">integer</field> - </object> - </object> - <object key="discount" dataType="default_checkout_totals_sort_order"> - <object key="inherit" dataType="checkoutTotalFlagZero"> - <field key="value">integer</field> - </object> - </object> - <object key="shipping" dataType="default_checkout_totals_sort_order"> - <object key="inherit" dataType="checkoutTotalFlagZero"> - <field key="value">integer</field> - </object> - </object> - <object key="tax" dataType="default_checkout_totals_sort_order"> - <object key="inherit" dataType="checkoutTotalFlagZero"> - <field key="value">integer</field> - </object> - </object> - <object key="weee" dataType="default_checkout_totals_sort_order"> - <object key="inherit" dataType="checkoutTotalFlagZero"> - <field key="value">integer</field> - </object> - </object> - <object key="grand_total" dataType="default_checkout_totals_sort_order"> - <object key="inherit" dataType="checkoutTotalFlagZero"> - <field key="value">integer</field> - </object> - </object> - <object key="giftcardaccount" dataType="giftcardaccount"> - <field key="value">integer</field> - </object> - <object key="customerbalance" dataType="customerbalance"> - <field key="value">integer</field> - </object> - </object> - </object> - </object> - </operation> -</operations> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml deleted file mode 100644 index 08623da68a8ef..0000000000000 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutTotalsSortOrderInCartTest.xml +++ /dev/null @@ -1,52 +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="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="CheckoutTotalsSortOrderInCartTest"> - <annotations> - <title value="Checkout Totals Sort Order configuration and displaying in cart"/> - <stories value="MAGETWO-91658: Wrong Checkout Totals Sort Order in cart"/> - <description value="Checkout Totals Sort Order configuration and displaying in cart"/> - <features value="Checkout"/> - <severity value="AVERAGE"/> - <testCaseId value="MAGETWO-94944"/> - <group value="Checkout"/> - </annotations> - - <before> - <createData entity="_defaultCategory" stepKey="defaultCategory"/> - <createData entity="SimpleProduct" stepKey="simpleProduct"> - <requiredEntity createDataKey="defaultCategory"/> - </createData> - - <createData entity="ApiCartRule" stepKey="cartRule"/> - - <createData entity="CheckoutShippingTotalsSortOrder" stepKey="setConfigShippingTotalsSortOrder"/> - </before> - - <actionGroup ref="VerifyDiscountAmount" stepKey="verifyStorefront"> - <argument name="productUrl" value="$$simpleProduct.sku$$.html"/> - <argument name="quantity" value="1"/> - <argument name="expectedDiscount" value="-$61.50"/> - </actionGroup> - - <actionGroup ref="CheckTotalsSortOrderInSummarySection" stepKey="checkTotalsSortOrderInSummarySection"> - <argument name="elementName" value="Shipping (Flat Rate - Fixed)"/> - <argument name="positionNumber" value="3"/> - </actionGroup> - - <after> - <createData entity="DefaultCheckoutTotalsSortOrder" stepKey="setDefaultTotalsSortOrder"/> - - <deleteData createDataKey="cartRule" stepKey="deleteCartRule"/> - <deleteData createDataKey="simpleProduct" stepKey="deleteProduct"/> - <deleteData createDataKey="defaultCategory" stepKey="deleteCategory"/> - - <magentoCLI command="cache:flush" stepKey="flushCache"/> - </after> - </test> -</tests> \ No newline at end of file From f631c90376dd2d217686e781147cc707bd816c8f Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Wed, 7 Nov 2018 14:36:22 +0200 Subject: [PATCH 696/812] magento/magento2#12970: [Forwardport] Can't add grouped product, with out of stock sub product, to cart. --- .../Model/Product/Type/Grouped.php | 2 +- .../_files/product_virtual_out_of_stock.php | 20 ++ .../product_virtual_out_of_stock_rollback.php | 26 +++ .../Model/Product/Type/GroupedTest.php | 194 ++++++++++++++++-- .../product_grouped_with_out_of_stock.php | 75 +++++++ ...uct_grouped_with_out_of_stock_rollback.php | 10 + 6 files changed, 311 insertions(+), 16 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php create mode 100644 dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php index 80824d45cb6e5..56de9ee9552ae 100644 --- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php +++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php @@ -347,7 +347,7 @@ protected function getProductInfo(\Magento\Framework\DataObject $buyRequest, $pr if ($isStrictProcessMode && !$subProduct->getQty()) { return __('Please specify the quantity of product(s).')->render(); } - $productsInfo[$subProduct->getId()] = (int)$subProduct->getQty(); + $productsInfo[$subProduct->getId()] = $subProduct->isSalable() ? (float)$subProduct->getQty() : 0; } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock.php new file mode 100644 index 0000000000000..cff2e83ed002e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock.php @@ -0,0 +1,20 @@ +<?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(\Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL) + ->setId(31) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Virtual Product Out') + ->setSku('virtual-product-out') + ->setPrice(10) + ->setTaxClassId(0) + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setStockData(['is_in_stock' => 0]) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock_rollback.php new file mode 100644 index 0000000000000..8055ca4a25569 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock_rollback.php @@ -0,0 +1,26 @@ +<?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() + ->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + +try { + $product = $productRepository->get('virtual-product-out', false, null, true); + $productRepository->delete($product); +} catch (\Magento\Framework\Exception\NoSuchEntityException $exception) { + //Product already removed +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php index dcf4565873ea5..ed283d196e69c 100644 --- a/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php @@ -5,8 +5,19 @@ */ namespace Magento\GroupedProduct\Model\Product\Type; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\CatalogInventory\Model\Configuration; +use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\Framework\App\Config\Value; + class GroupedTest extends \PHPUnit\Framework\TestCase { + /** + * @var ReinitableConfigInterface + */ + private $reinitableConfig; + /** * @var \Magento\Framework\ObjectManagerInterface */ @@ -20,16 +31,21 @@ class GroupedTest extends \PHPUnit\Framework\TestCase protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->_productType = $this->objectManager->get(\Magento\Catalog\Model\Product\Type::class); + $this->reinitableConfig = $this->objectManager->get(ReinitableConfigInterface::class); + } + + protected function tearDown() + { + $this->dropConfigValue(Configuration::XML_PATH_SHOW_OUT_OF_STOCK); } public function testFactory() { $product = new \Magento\Framework\DataObject(); - $product->setTypeId(\Magento\GroupedProduct\Model\Product\Type\Grouped::TYPE_CODE); + $product->setTypeId(Grouped::TYPE_CODE); $type = $this->_productType->factory($product); - $this->assertInstanceOf(\Magento\GroupedProduct\Model\Product\Type\Grouped::class, $type); + $this->assertInstanceOf(Grouped::class, $type); } /** @@ -38,12 +54,12 @@ public function testFactory() */ public function testGetAssociatedProducts() { - $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); - /** @var \Magento\Catalog\Model\Product $product */ + /** @var Product $product */ $product = $productRepository->get('grouped-product'); $type = $product->getTypeInstance(); - $this->assertInstanceOf(\Magento\GroupedProduct\Model\Product\Type\Grouped::class, $type); + $this->assertInstanceOf(Grouped::class, $type); $associatedProducts = $type->getAssociatedProducts($product); $this->assertCount(2, $associatedProducts); @@ -53,7 +69,7 @@ public function testGetAssociatedProducts() } /** - * @param \Magento\Catalog\Model\Product $product + * @param Product $product */ private function assertProductInfo($product) { @@ -92,25 +108,25 @@ public function testPrepareProduct() \Magento\Framework\DataObject::class, ['data' => ['value' => ['qty' => 2]]] ); - /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ - $productRepository = $this->objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); $product = $productRepository->get('grouped-product'); - /** @var \Magento\GroupedProduct\Model\Product\Type\Grouped $type */ - $type = $this->objectManager->get(\Magento\GroupedProduct\Model\Product\Type\Grouped::class); + /** @var Grouped $type */ + $type = $this->objectManager->get(Grouped::class); $processModes = [ - \Magento\GroupedProduct\Model\Product\Type\Grouped::PROCESS_MODE_FULL, - \Magento\GroupedProduct\Model\Product\Type\Grouped::PROCESS_MODE_LITE + Grouped::PROCESS_MODE_FULL, + Grouped::PROCESS_MODE_LITE ]; $expectedData = [ - \Magento\GroupedProduct\Model\Product\Type\Grouped::PROCESS_MODE_FULL => [ + Grouped::PROCESS_MODE_FULL => [ 1 => '{"super_product_config":{"product_type":"grouped","product_id":"' . $product->getId() . '"}}', 21 => '{"super_product_config":{"product_type":"grouped","product_id":"' . $product->getId() . '"}}', ], - \Magento\GroupedProduct\Model\Product\Type\Grouped::PROCESS_MODE_LITE => [ + Grouped::PROCESS_MODE_LITE => [ $product->getId() => '{"value":{"qty":2}}', ] ]; @@ -127,4 +143,152 @@ public function testPrepareProduct() } } } + + /** + * Test adding grouped product to cart when one of subproducts is out of stock. + * + * @magentoDataFixture Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php + * @magentoAppArea frontend + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled + * @dataProvider outOfStockSubProductDataProvider + * @param bool $outOfStockShown + * @param array $data + * @param array $expected + */ + public function testOutOfStockSubProduct(bool $outOfStockShown, array $data, array $expected) + { + $this->changeConfigValue(Configuration::XML_PATH_SHOW_OUT_OF_STOCK, $outOfStockShown); + $buyRequest = new \Magento\Framework\DataObject($data); + $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + /** @var Product $product */ + $product = $productRepository->get('grouped-product'); + /** @var Grouped $groupedProduct */ + $groupedProduct = $this->objectManager->get(Grouped::class); + $actual = $groupedProduct->prepareForCartAdvanced($buyRequest, $product, Grouped::PROCESS_MODE_FULL); + self::assertEquals( + count($expected), + count($actual) + ); + /** @var Product $product */ + foreach ($actual as $product) { + $sku = $product->getSku(); + self::assertEquals( + $expected[$sku], + $product->getCartQty(), + "Failed asserting that Product Cart Quantity matches expected" + ); + } + } + + /** + * Data provider for testOutOfStockSubProduct. + * + * @return array + */ + public function outOfStockSubProductDataProvider() + { + return [ + 'Out of stock product are shown #1' => [ + true, + [ + 'product' => 3, + 'qty' => 1, + 'super_group' => [ + 1 => 4, + 21 => 5, + ], + ], + [ + 'virtual-product' => 5, + 'simple' => 4 + ], + ], + 'Out of stock product are shown #2' => [ + true, + [ + 'product' => 3, + 'qty' => 1, + 'super_group' => [ + 1 => 0, + ], + ], + [ + 'virtual-product' => 2.5, // This is a default quantity. + ], + ], + 'Out of stock product are hidden #1' => [ + false, + [ + 'product' => 3, + 'qty' => 1, + 'super_group' => [ + 1 => 4, + 21 => 5, + ], + ], + [ + 'virtual-product' => 5, + 'simple' => 4, + ], + ], + 'Out of stock product are hidden #2' => [ + false, + [ + 'product' => 3, + 'qty' => 1, + 'super_group' => [ + 1 => 0, + ], + ], + [ + 'virtual-product' => 2.5, // This is a default quantity. + ], + ], + ]; + } + + /** + * Write config value to database. + * + * @param string $path + * @param string $value + * @param string $scope + * @param int $scopeId + */ + private function changeConfigValue(string $path, string $value, string $scope = 'default', int $scopeId = 0) + { + $configValue = $this->objectManager->create(Value::class); + $configValue->setPath($path) + ->setValue($value) + ->setScope($scope) + ->setScopeId($scopeId) + ->save(); + $this->reinitConfig(); + } + + /** + * Delete config value from database. + * + * @param string $path + */ + private function dropConfigValue(string $path) + { + $configValue = $this->objectManager->create(Value::class); + try { + $configValue->load($path, 'path'); + $configValue->delete(); + } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + // do nothing + } + $this->reinitConfig(); + } + + /** + * Reinit config. + */ + private function reinitConfig() + { + $this->reinitableConfig->reinit(); + } } diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php new file mode 100644 index 0000000000000..7aa62b149b8c0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php @@ -0,0 +1,75 @@ +\<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require realpath(__DIR__ . '/../../') . '/Catalog/_files/product_associated.php'; +require realpath(__DIR__ . '/../../') . '/Catalog/_files/product_virtual_in_stock.php'; +require realpath(__DIR__ . '/../../') . '/Catalog/_files/product_virtual_out_of_stock.php'; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId( + \Magento\GroupedProduct\Model\Product\Type\Grouped::TYPE_CODE +)->setAttributeSetId( + 4 +)->setWebsiteIds( + [1] +)->setName( + 'Grouped Product' +)->setSku( + 'grouped-product' +)->setPrice( + 100 +)->setTaxClassId( + 0 +)->setVisibility( + \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH +)->setStatus( + \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED +); + +$newLinks = []; +$productLinkFactory = $objectManager->get(\Magento\Catalog\Api\Data\ProductLinkInterfaceFactory::class); + +/** @var \Magento\Catalog\Api\Data\ProductLinkInterface $productLink */ +$productLink = $productLinkFactory->create(); +$linkedProduct = $productRepository->getById(1); +$productLink->setSku($product->getSku()) + ->setLinkType('associated') + ->setLinkedProductSku($linkedProduct->getSku()) + ->setLinkedProductType($linkedProduct->getTypeId()) + ->setPosition(1) + ->getExtensionAttributes() + ->setQty(1); +$newLinks[] = $productLink; + +$subProductsSkus = ['virtual-product', 'virtual-product-out']; +foreach ($subProductsSkus as $sku) { + /** @var \Magento\Catalog\Api\Data\ProductLinkInterface $productLink */ + $productLink = $productLinkFactory->create(); + $linkedProduct = $productRepository->get($sku); + $productLink->setSku($product->getSku()) + ->setLinkType('associated') + ->setLinkedProductSku($sku) + ->setLinkedProductType($linkedProduct->getTypeId()) + ->getExtensionAttributes() + ->setQty(2.5); + $newLinks[] = $productLink; +} +$product->setProductLinks($newLinks); +$product->save(); + +/** @var \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement */ +$categoryLinkManagement = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Api\CategoryLinkManagementInterface::class); + +$categoryLinkManagement->assignProductToCategories( + $product->getSku(), + [2] +); diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php new file mode 100644 index 0000000000000..48e7d495f8985 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php @@ -0,0 +1,10 @@ +\<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'product_grouped_rollback.php'; +require realpath(__DIR__ . '/../../') . '/Catalog/_files/product_virtual_out_of_stock_rollback.php'; +require realpath(__DIR__ . '/../../') . '/Catalog/_files/product_virtual_in_stock_rollback.php'; +require realpath(__DIR__ . '/../../') . '/Catalog/_files/product_associated_rollback.php'; From 2cab212809680085450836442c9346130c1f6440 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Wed, 7 Nov 2018 16:02:31 +0200 Subject: [PATCH 697/812] Covering the \Magento\Weee\Observer\AddPaymentWeeeItem by Unit Test --- .../Unit/Observer/AddPaymentWeeeItemTest.php | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php diff --git a/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php b/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php new file mode 100644 index 0000000000000..1e707b118dccb --- /dev/null +++ b/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php @@ -0,0 +1,154 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Weee\Test\Unit\Observer; + +use Magento\Framework\Event; +use Magento\Framework\Event\Observer; +use Magento\Payment\Model\Cart; +use Magento\Payment\Model\Cart\SalesModel\SalesModelInterface; +use Magento\Quote\Model\Quote\Item; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Weee\Helper\Data; +use Magento\Weee\Observer\AddPaymentWeeeItem; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +/** + * Class AddPaymentWeeeItemTest + */ +class AddPaymentWeeeItemTest extends TestCase +{ + /** + * Testable object + * + * @var AddPaymentWeeeItem + */ + private $observer; + + /** + * @var Data|MockObject + */ + private $weeeHelperMock; + + /** + * @var StoreManagerInterface|MockObject + */ + private $storeManagerMock; + + /** + * Set Up + */ + protected function setUp() + { + $this->weeeHelperMock = $this->createMock(Data::class); + $this->storeManagerMock = $this->createMock(StoreManagerInterface::class); + + $this->observer = new AddPaymentWeeeItem( + $this->weeeHelperMock, + $this->storeManagerMock + ); + } + + /** + * Test execute + * + * @dataProvider dataProvider + * @param $isEnabled + * @param $includeInSubtotal + * @return void + */ + public function testExecute($isEnabled, $includeInSubtotal): void + { + /** @var Observer|MockObject $observerMock */ + $observerMock = $this->createMock(Observer::class); + $cartModelMock = $this->createMock(Cart::class); + $salesModelMock = $this->createMock(SalesModelInterface::class); + $itemMock = $this->createPartialMock(Item::class, ['getOriginalItem']); + $originalItemMock = $this->createPartialMock(Item::class, ['getParentItem']); + $parentItemMock = $this->createMock(Item::class); + $eventMock = $this->getMockBuilder(Event::class) + ->disableOriginalConstructor() + ->setMethods(['getCart']) + ->getMock(); + + $asCustomItem = $this->prepareShouldBeAddedAsCustomItem($isEnabled, $includeInSubtotal); + $toBeCalled = 1; + if (!$asCustomItem) { + $toBeCalled = 0; + } + + $eventMock->expects($this->exactly($toBeCalled)) + ->method('getCart') + ->willReturn($cartModelMock); + $observerMock->expects($this->exactly($toBeCalled)) + ->method('getEvent') + ->willReturn($eventMock); + $itemMock->expects($this->exactly($toBeCalled)) + ->method('getOriginalItem') + ->willReturn($originalItemMock); + $originalItemMock->expects($this->exactly($toBeCalled)) + ->method('getParentItem') + ->willReturn($parentItemMock); + $salesModelMock->expects($this->exactly($toBeCalled)) + ->method('getAllItems') + ->willReturn([$itemMock]); + $cartModelMock->expects($this->exactly($toBeCalled)) + ->method('getSalesModel') + ->willReturn($salesModelMock); + + $this->observer->execute($observerMock); + } + + /** + * @return array + */ + public function dataProvider(): array + { + return [ + [true, false], + [true, true], + [false, true], + [false, false], + ]; + } + + /** + * Prepare if FPT should be added to payment cart as custom item or not. + * + * @param $isEnabled + * @param $includeInSubtotal + * @return bool + */ + private function prepareShouldBeAddedAsCustomItem(bool $isEnabled, bool $includeInSubtotal): bool + { + $storeMock = $this->getMockBuilder(StoreInterface::class) + ->setMethods(['getId']) + ->getMockForAbstractClass(); + $storeMock->expects($this->once()) + ->method('getId') + ->willReturn(Store::DEFAULT_STORE_ID); + $this->storeManagerMock->expects($this->once()) + ->method('getStore') + ->willReturn($storeMock); + $this->weeeHelperMock->expects($this->once()) + ->method('isEnabled') + ->with(Store::DEFAULT_STORE_ID) + ->willReturn($isEnabled); + + if ($isEnabled) { + $this->weeeHelperMock->expects($this->once()) + ->method('includeInSubtotal') + ->with(Store::DEFAULT_STORE_ID) + ->willReturn($includeInSubtotal); + } + + return $isEnabled && !$includeInSubtotal; + } +} From bb20a8b757ca43f16b63e98dd97aa5c6f630eaa0 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Wed, 7 Nov 2018 16:45:52 +0200 Subject: [PATCH 698/812] Small refactoring. Covering the SetWeeeRendererInFormObserver class by Unit Test --- .../Unit/Observer/AddPaymentWeeeItemTest.php | 10 +-- .../SetWeeeRendererInFormObserverTest.php | 88 +++++++++++++++++++ 2 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 app/code/Magento/Weee/Test/Unit/Observer/SetWeeeRendererInFormObserverTest.php diff --git a/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php b/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php index 1e707b118dccb..dd0547354cfa4 100644 --- a/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php +++ b/app/code/Magento/Weee/Test/Unit/Observer/AddPaymentWeeeItemTest.php @@ -60,11 +60,11 @@ protected function setUp() * Test execute * * @dataProvider dataProvider - * @param $isEnabled - * @param $includeInSubtotal + * @param bool $isEnabled + * @param bool $includeInSubtotal * @return void */ - public function testExecute($isEnabled, $includeInSubtotal): void + public function testExecute(bool $isEnabled, bool $includeInSubtotal): void { /** @var Observer|MockObject $observerMock */ $observerMock = $this->createMock(Observer::class); @@ -122,8 +122,8 @@ public function dataProvider(): array /** * Prepare if FPT should be added to payment cart as custom item or not. * - * @param $isEnabled - * @param $includeInSubtotal + * @param bool $isEnabled + * @param bool $includeInSubtotal * @return bool */ private function prepareShouldBeAddedAsCustomItem(bool $isEnabled, bool $includeInSubtotal): bool diff --git a/app/code/Magento/Weee/Test/Unit/Observer/SetWeeeRendererInFormObserverTest.php b/app/code/Magento/Weee/Test/Unit/Observer/SetWeeeRendererInFormObserverTest.php new file mode 100644 index 0000000000000..188b42cb37906 --- /dev/null +++ b/app/code/Magento/Weee/Test/Unit/Observer/SetWeeeRendererInFormObserverTest.php @@ -0,0 +1,88 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Weee\Test\Unit\Observer; + +use Magento\Framework\Data\Form; +use Magento\Framework\Event; +use Magento\Framework\Event\Observer; +use Magento\Framework\View\LayoutInterface; +use Magento\Weee\Model\Tax; +use Magento\Weee\Observer\SetWeeeRendererInFormObserver; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +/** + * Class AddPaymentWeeeItemTest + */ +class SetWeeeRendererInFormObserverTest extends TestCase +{ + /** + * Testable object + * + * @var SetWeeeRendererInFormObserver + */ + private $observer; + + /** + * @var LayoutInterface|MockObject + */ + private $layoutMock; + + /** + * @var Tax|MockObject + */ + private $taxModelMock; + + /** + * Set Up + */ + protected function setUp() + { + $this->layoutMock = $this->createMock(LayoutInterface::class); + $this->taxModelMock = $this->createMock(Tax::class); + $this->observer = new SetWeeeRendererInFormObserver( + $this->layoutMock, + $this->taxModelMock + ); + } + + /** + * Test assigning a custom renderer for product create/edit form weee attribute element + * + * @return void + */ + public function testExecute(): void + { + $attributes = new \ArrayIterator(['element_code_1', 'element_code_2']); + /** @var Event|MockObject $eventMock */ + $eventMock = $this->getMockBuilder(Event::class) + ->disableOriginalConstructor() + ->setMethods(['getForm']) + ->getMock(); + + /** @var Observer|MockObject $observerMock */ + $observerMock = $this->createMock(Observer::class); + /** @var Form|MockObject $formMock */ + $formMock = $this->createMock(Form::class); + + $eventMock->expects($this->once()) + ->method('getForm') + ->willReturn($formMock); + $observerMock->expects($this->once()) + ->method('getEvent') + ->willReturn($eventMock); + $this->taxModelMock->expects($this->once()) + ->method('getWeeeAttributeCodes') + ->willReturn($attributes); + $formMock->expects($this->exactly($attributes->count())) + ->method('getElement') + ->willReturnSelf(); + + $this->observer->execute($observerMock); + } +} From 773746968337a08d5f89f5a09113dd763bc0577f Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Wed, 7 Nov 2018 17:18:24 +0200 Subject: [PATCH 699/812] magento-engcom/magento2ce#2316: Code style fixes --- app/code/Magento/Catalog/Model/Design.php | 5 +++-- lib/internal/Magento/Framework/Translate.php | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Design.php b/app/code/Magento/Catalog/Model/Design.php index 6c0629feaf6fd..853bbeac8eb38 100644 --- a/app/code/Magento/Catalog/Model/Design.php +++ b/app/code/Magento/Catalog/Model/Design.php @@ -43,9 +43,10 @@ class Design extends \Magento\Framework\Model\AbstractModel * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate * @param \Magento\Framework\View\DesignInterface $design - * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource - * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection + * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource + * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection * @param array $data + * @param TranslateInterface|null $translator */ public function __construct( \Magento\Framework\Model\Context $context, diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index ff1bf99162a8a..f889549a107a8 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -278,6 +278,7 @@ protected function getConfig($key) /** * Retrieve name of the current module + * * @return mixed */ protected function getControllerModuleName() From d7fca7216491ac404b00ca6ff43d0ac6751a5597 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 6 Nov 2018 19:26:30 -0600 Subject: [PATCH 700/812] MAGETWO-95745: Signifyd case not created for WorldPay - revert MAGETWO-94269 --- .../Paypal/Controller/Payflow/ReturnUrl.php | 4 ++-- .../Unit/Controller/Payflow/ReturnUrlTest.php | 16 ---------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php b/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php index 56a5da40edb85..cf932f046d1be 100644 --- a/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php +++ b/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php @@ -6,6 +6,7 @@ */ namespace Magento\Paypal\Controller\Payflow; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\App\CsrfAwareActionInterface; use Magento\Framework\App\Request\InvalidRequestException; use Magento\Framework\App\RequestInterface; @@ -13,7 +14,7 @@ use Magento\Paypal\Model\Config; use Magento\Sales\Model\Order; -class ReturnUrl extends Payflow implements CsrfAwareActionInterface +class ReturnUrl extends Payflow implements CsrfAwareActionInterface, HttpGetActionInterface { /** * @var array of allowed order states on frontend @@ -68,7 +69,6 @@ public function execute() if ($order->getIncrementId()) { if ($this->checkOrderState($order)) { $redirectBlock->setData('goto_success_page', true); - $this->_eventManager->dispatch('paypal_checkout_success', ['order' => $order]); } else { if ($this->checkPaymentMethod($order)) { $gotoSection = $this->_cancelPayment((string)$this->getRequest()->getParam('RESPMSG')); diff --git a/app/code/Magento/Paypal/Test/Unit/Controller/Payflow/ReturnUrlTest.php b/app/code/Magento/Paypal/Test/Unit/Controller/Payflow/ReturnUrlTest.php index 44775d7e381bb..32d3f2c73b159 100644 --- a/app/code/Magento/Paypal/Test/Unit/Controller/Payflow/ReturnUrlTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Controller/Payflow/ReturnUrlTest.php @@ -5,7 +5,6 @@ */ namespace Magento\Paypal\Test\Unit\Controller\Payflow; -use Magento\Framework\Event\ManagerInterface; use Magento\Sales\Api\PaymentFailuresInterface; use Magento\Checkout\Block\Onepage\Success; use Magento\Checkout\Model\Session; @@ -97,11 +96,6 @@ class ReturnUrlTest extends \PHPUnit\Framework\TestCase */ private $paymentFailures; - /** - * @var ManagerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $eventManagerMock; - /** * @inheritdoc */ @@ -158,16 +152,10 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - $this->eventManagerMock = $this->getMockBuilder(ManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->context->method('getView') ->willReturn($this->view); $this->context->method('getRequest') ->willReturn($this->request); - $this->context->method('getEventManager') - ->willReturn($this->eventManagerMock); $this->returnUrl = $this->objectManager->getObject( ReturnUrl::class, @@ -199,10 +187,6 @@ public function testExecuteAllowedOrderState($state) ->with('goto_success_page', true) ->willReturnSelf(); - $this->eventManagerMock->expects($this->once()) - ->method('dispatch') - ->with('paypal_checkout_success', $this->arrayHasKey('order')); - $result = $this->returnUrl->execute(); $this->assertNull($result); } From 385b01ef801cfa5fc5e2745bd71154bee85f8c3b Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 7 Nov 2018 10:58:54 -0600 Subject: [PATCH 701/812] MAGETWO-95745: Signifyd case not created for WorldPay - revert MAGETWO-71763 --- app/code/Magento/Signifyd/etc/events.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Signifyd/etc/events.xml b/app/code/Magento/Signifyd/etc/events.xml index e6418e2fdb6b4..d44665f9fb97b 100644 --- a/app/code/Magento/Signifyd/etc/events.xml +++ b/app/code/Magento/Signifyd/etc/events.xml @@ -9,9 +9,6 @@ <event name="checkout_submit_all_after"> <observer name="signifyd_place_order_observer" instance="Magento\Signifyd\Observer\PlaceOrder" /> </event> - <event name="paypal_express_place_order_success"> - <observer name="signifyd_place_order_paypal_express_observer" instance="Magento\Signifyd\Observer\PlaceOrder"/> - </event> <event name="paypal_checkout_success"> <observer name="signifyd_place_order_checkout_success_observer" instance="Magento\Signifyd\Observer\PlaceOrder" /> </event> From 436f0d995df9c0a374ec504f4302d2bf6e909af5 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 7 Nov 2018 11:32:54 -0600 Subject: [PATCH 702/812] MAGETWO-95745: Signifyd case not created for WorldPay - fix static test failures --- app/code/Magento/Checkout/Controller/Onepage/Success.php | 4 +++- app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Controller/Onepage/Success.php b/app/code/Magento/Checkout/Controller/Onepage/Success.php index e0872b425cc7c..a657b23cca4d6 100644 --- a/app/code/Magento/Checkout/Controller/Onepage/Success.php +++ b/app/code/Magento/Checkout/Controller/Onepage/Success.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -8,6 +7,9 @@ use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface; +/** + * Onepage checkout success controller class + */ class Success extends \Magento\Checkout\Controller\Onepage implements HttpGetActionInterface { /** diff --git a/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php b/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php index cf932f046d1be..d2a14febe54dd 100644 --- a/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php +++ b/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -14,6 +13,9 @@ use Magento\Paypal\Model\Config; use Magento\Sales\Model\Order; +/** + * Paypal Payflow ReturnUrl controller class + */ class ReturnUrl extends Payflow implements CsrfAwareActionInterface, HttpGetActionInterface { /** From 240cfb3e8b2ed77cf63566d7326e537771e8bceb Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Wed, 7 Nov 2018 20:35:18 +0200 Subject: [PATCH 703/812] graphQl: fixed typos and wrong descriptions --- .../QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php | 8 ++++---- .../Model/Cart/SetShippingAddressesOnCartInterface.php | 3 ++- app/code/Magento/QuoteGraphQl/etc/schema.graphqls | 3 +-- .../GraphQl/Quote/SetShippingAddressOnCartTest.php | 9 ++++----- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php index 588d4f65cc565..960900682db4c 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php @@ -59,7 +59,7 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s { if (count($shippingAddresses) > 1) { throw new GraphQlInputException( - __('Multiple addresses do not allowed here!') + __('You cannot specify multiple shipping addresses.') ); } $shippingAddress = current($shippingAddresses); @@ -68,19 +68,19 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s if (!$customerAddressId && !$addressInput) { throw new GraphQlInputException( - __('Shipping address should contain either "customer_address_id" or "address" input.') + __('The shipping address must contain either "customer_address_id" or "address".') ); } if ($customerAddressId && $addressInput) { throw new GraphQlInputException( - __('Shipping address can\'t contain "customer_address_id" and "address" input at the same time.') + __('The shipping address cannot contain "customer_address_id" and "address" at the same time.') ); } if ($customerAddressId) { if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { throw new GraphQlAuthorizationException( __( - 'Address management allowed only for authorized customers.' + 'Guest users cannot manage addresses.' ) ); } diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php index ae337240c3a26..dde9cce9d8693 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php @@ -14,7 +14,8 @@ /** * Extension point for setting shipping addresses for a specified shopping cart * - * All objects that are responsible for set shipping addresses on cart via GraphQl should implement this interface. + * All objects that are responsible for setting shipping addresses on a cart via GraphQl + *should implement this interface. */ interface SetShippingAddressesOnCartInterface { diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 017b1f8119829..15d90c352ba62 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -6,11 +6,10 @@ type Query { } type Mutation { - createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") + createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates an empty shopping cart for a guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingAddressesOnCart") - createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveCouponFromCart") setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php index 48ef8ebb790d1..2b4223cf67a89 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php @@ -139,13 +139,12 @@ public function testSetSavedShippingAddressOnCartByGuest() } } QUERY; - self::expectExceptionMessage('Address management allowed only for authorized customers.'); + self::expectExceptionMessage('Guest users cannot manage addresses.'); $this->graphQlQuery($query); } /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php - * @magentoConfigFixture default_store multishipping/options/checkout_multiple 0 */ public function testSetMultipleShippingAddressesOnCartByGuest() { @@ -185,7 +184,7 @@ public function testSetMultipleShippingAddressesOnCartByGuest() } } QUERY; - self::expectExceptionMessage('Multiple addresses do not allowed here!'); + self::expectExceptionMessage('You cannot specify multiple shipping addresses.'); $this->graphQlQuery($query); } @@ -240,7 +239,7 @@ public function testSetSavedAndNewShippingAddressOnCartAtTheSameTime() } QUERY; self::expectExceptionMessage( - 'Shipping address can\'t contain "customer_address_id" and "address" input at the same time.' + 'The shipping address cannot contain "customer_address_id" and "address" at the same time.' ); $this->graphQlQuery($query); } @@ -282,7 +281,7 @@ public function testSetShippingAddressOnCartWithNoAddresses() } QUERY; self::expectExceptionMessage( - 'Shipping address should contain either "customer_address_id" or "address" input.' + 'The shipping address must contain either "customer_address_id" or "address".' ); $this->graphQlQuery($query); } From b490fb16a0e21eb4b11327d4dcc2e54ebdfdaca4 Mon Sep 17 00:00:00 2001 From: larsroettig <l.roettig@techdivision.com> Date: Wed, 7 Nov 2018 20:35:28 +0100 Subject: [PATCH 704/812] #18956 Add TestCase for no root_category_id set --- .../Config/Importer/Processor/CreateTest.php | 55 +++++++++++++------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php index 0901464224399..0fbf7bb7f044b 100644 --- a/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/Config/Importer/Processor/CreateTest.php @@ -196,14 +196,30 @@ private function initTestData() 'root_category_id' => '1', 'default_store_id' => '1', 'code' => 'default', + ], + 2 => [ + 'group_id' => '1', + 'website_id' => '1', + 'name' => 'Default1', + 'default_store_id' => '1', + 'code' => 'default1', ] ]; - $this->trimmedGroup = [ - 'name' => 'Default', - 'root_category_id' => '1', - 'code' => 'default', - 'default_store_id' => '1', - ]; + $this->trimmedGroup = + [ + 0 => [ + 'name' => 'Default', + 'root_category_id' => '1', + 'code' => 'default', + 'default_store_id' => '1', + ], + 1 => [ + 'name' => 'Default1', + 'root_category_id' => '0', + 'code' => 'default1', + 'default_store_id' => '1' + ] + ]; $this->stores = [ 'default' => [ 'store_id' => '1', @@ -280,31 +296,34 @@ public function testRunGroup() [ScopeInterface::SCOPE_GROUPS, $this->groups, $this->groups], ]); - $this->websiteMock->expects($this->once()) + $this->websiteMock->expects($this->exactly(2)) ->method('getResource') ->willReturn($this->abstractDbMock); - $this->groupMock->expects($this->once()) + $this->groupMock->expects($this->exactly(2)) ->method('setData') - ->with($this->trimmedGroup) - ->willReturnSelf(); - $this->groupMock->expects($this->exactly(3)) + ->withConsecutive( + [$this->equalTo($this->trimmedGroup[0])], + [$this->equalTo($this->trimmedGroup[1])] + )->willReturnSelf(); + + $this->groupMock->expects($this->exactly(6)) ->method('getResource') ->willReturn($this->abstractDbMock); - $this->groupMock->expects($this->once()) + $this->groupMock->expects($this->exactly(2)) ->method('getDefaultStoreId') ->willReturn($defaultStoreId); - $this->groupMock->expects($this->once()) + $this->groupMock->expects($this->exactly(2)) ->method('setDefaultStoreId') ->with($storeId); - $this->groupMock->expects($this->once()) + $this->groupMock->expects($this->exactly(2)) ->method('setWebsite') ->with($this->websiteMock); - $this->storeMock->expects($this->once()) + $this->storeMock->expects($this->exactly(2)) ->method('getResource') ->willReturn($this->abstractDbMock); - $this->storeMock->expects($this->once()) + $this->storeMock->expects($this->exactly(2)) ->method('getStoreId') ->willReturn($storeId); @@ -312,11 +331,11 @@ public function testRunGroup() ->method('load') ->withConsecutive([$this->websiteMock, 'base', 'code'], [$this->storeMock, 'default', 'code']) ->willReturnSelf(); - $this->abstractDbMock->expects($this->exactly(2)) + $this->abstractDbMock->expects($this->exactly(4)) ->method('save') ->with($this->groupMock) ->willReturnSelf(); - $this->abstractDbMock->expects($this->once()) + $this->abstractDbMock->expects($this->exactly(2)) ->method('addCommitCallback') ->willReturnCallback(function ($function) { return $function(); From b027ce062c33745cc23fae044566520c584ba459 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 7 Nov 2018 16:25:57 -0600 Subject: [PATCH 705/812] ENGCOM-3409: Skip randomly failing tests in PR #2316 --- ...dminSubmitConfigurableProductOrderTest.xml | 259 +++++++++--------- .../Test/Mftf/Test/AdminTaxReportGridTest.xml | 3 + .../Mftf/Test/StorefrontTaxQuoteCartTest.xml | 3 + 3 files changed, 137 insertions(+), 128 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitConfigurableProductOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitConfigurableProductOrderTest.xml index e32e6b9e6ec5d..ff1e27a2efa08 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitConfigurableProductOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitConfigurableProductOrderTest.xml @@ -1,129 +1,132 @@ -<?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="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> - <test name="AdminSubmitConfigurableProductOrderTest"> - <annotations> - <title value="Create Order in Admin and update product configuration"/> - <stories value="MAGETWO-59632: Create Sales > Order from admin add configurable product and change options click OK does not update Items Ordered List"/> - <description value="Create Order in Admin and update product configuration"/> - <features value="Sales"/> - <severity value="AVERAGE"/> - <testCaseId value="MAGETWO-59633"/> - <group value="Sales"/> - </annotations> - - <before> - <!--Set default flat rate shipping method settings--> - <createData entity="FlatRateShippingMethodDefault" stepKey="setDefaultFlatRateShippingMethod"/> - - <!--Create simple customer--> - <createData entity="Simple_US_Customer_CA" stepKey="simpleCustomer"/> - - <!-- Create the category --> - <createData entity="ApiCategory" stepKey="createCategory"/> - - <!-- Create the configurable product and add it to the category --> - <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> - <requiredEntity createDataKey="createCategory"/> - </createData> - - <!-- Create an attribute with two options to be used in the first child product --> - <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> - <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </createData> - <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </createData> - - <!-- Add the attribute we just created to default attribute set --> - <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </createData> - - <!-- Get the option of the attribute we created --> - <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </getData> - <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </getData> - - <!-- Create a simple product and give it the attribute with option --> - <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - <requiredEntity createDataKey="getConfigAttributeOption1"/> - </createData> - <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - <requiredEntity createDataKey="getConfigAttributeOption2"/> - </createData> - - <!-- Create the configurable product --> - <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> - <requiredEntity createDataKey="createConfigProduct"/> - <requiredEntity createDataKey="createConfigProductAttribute"/> - <requiredEntity createDataKey="getConfigAttributeOption1"/> - <requiredEntity createDataKey="getConfigAttributeOption2"/> - </createData> - - <!-- Add simple product to the configurable product --> - <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> - <requiredEntity createDataKey="createConfigProduct"/> - <requiredEntity createDataKey="createConfigChildProduct1"/> - </createData> - <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> - <requiredEntity createDataKey="createConfigProduct"/> - <requiredEntity createDataKey="createConfigChildProduct2"/> - </createData> - - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - </before> - - <!--Create new customer order--> - <actionGroup ref="navigateToNewOrderPageExistingCustomer" stepKey="navigateToNewOrderWithExistingCustomer"> - <argument name="customer" value="$$simpleCustomer$$"/> - </actionGroup> - - <!--Add configurable product to order--> - <actionGroup ref="addConfigurableProductToOrderFromAdmin" stepKey="addConfigurableProductToOrder"> - <argument name="product" value="$$createConfigProduct$$"/> - <argument name="attribute" value="$$createConfigProductAttribute$$"/> - <argument name="option" value="$$getConfigAttributeOption1$$"/> - </actionGroup> - - <!--Configure ordered configurable product--> - <actionGroup ref="configureOrderedConfigurableProduct" stepKey="configureOrderedConfigurableProduct"> - <argument name="attribute" value="$$createConfigProductAttribute$$"/> - <argument name="option" value="$$getConfigAttributeOption2$$"/> - <argument name="quantity" value="2"/> - </actionGroup> - - <!--Select FlatRate shipping method--> - <actionGroup ref="orderSelectFlatRateShipping" stepKey="orderSelectFlatRateShippingMethod"/> - - <!--Submit order--> - <click selector="{{AdminOrderFormActionSection.SubmitOrder}}" stepKey="submitOrder"/> - - <!--Verify order information--> - <actionGroup ref="verifyCreatedOrderInformation" stepKey="verifyCreatedOrderInformation"/> - - <after> - <actionGroup ref="logout" stepKey="logout"/> - - <deleteData createDataKey="simpleCustomer" stepKey="deleteSimpleCustomer"/> - - <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> - <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> - <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> - <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> - <deleteData createDataKey="createCategory" stepKey="deleteApiCategory"/> - </after> - </test> +<?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="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminSubmitConfigurableProductOrderTest"> + <annotations> + <title value="Create Order in Admin and update product configuration"/> + <stories value="MAGETWO-59632: Create Sales > Order from admin add configurable product and change options click OK does not update Items Ordered List"/> + <description value="Create Order in Admin and update product configuration"/> + <features value="Sales"/> + <severity value="AVERAGE"/> + <testCaseId value="MAGETWO-59633"/> + <group value="Sales"/> + <skip> + <issueId value="MAGETWO-96196"/> + </skip> + </annotations> + + <before> + <!--Set default flat rate shipping method settings--> + <createData entity="FlatRateShippingMethodDefault" stepKey="setDefaultFlatRateShippingMethod"/> + + <!--Create simple customer--> + <createData entity="Simple_US_Customer_CA" stepKey="simpleCustomer"/> + + <!-- Create the category --> + <createData entity="ApiCategory" stepKey="createCategory"/> + + <!-- Create the configurable product and add it to the category --> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + + <!-- Create an attribute with two options to be used in the first child product --> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + + <!-- Add the attribute we just created to default attribute set --> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + + <!-- Get the option of the attribute we created --> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + + <!-- Create a simple product and give it the attribute with option --> + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + + <!-- Create the configurable product --> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + + <!-- Add simple product to the configurable product --> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <!--Create new customer order--> + <actionGroup ref="navigateToNewOrderPageExistingCustomer" stepKey="navigateToNewOrderWithExistingCustomer"> + <argument name="customer" value="$$simpleCustomer$$"/> + </actionGroup> + + <!--Add configurable product to order--> + <actionGroup ref="addConfigurableProductToOrderFromAdmin" stepKey="addConfigurableProductToOrder"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="attribute" value="$$createConfigProductAttribute$$"/> + <argument name="option" value="$$getConfigAttributeOption1$$"/> + </actionGroup> + + <!--Configure ordered configurable product--> + <actionGroup ref="configureOrderedConfigurableProduct" stepKey="configureOrderedConfigurableProduct"> + <argument name="attribute" value="$$createConfigProductAttribute$$"/> + <argument name="option" value="$$getConfigAttributeOption2$$"/> + <argument name="quantity" value="2"/> + </actionGroup> + + <!--Select FlatRate shipping method--> + <actionGroup ref="orderSelectFlatRateShipping" stepKey="orderSelectFlatRateShippingMethod"/> + + <!--Submit order--> + <click selector="{{AdminOrderFormActionSection.SubmitOrder}}" stepKey="submitOrder"/> + + <!--Verify order information--> + <actionGroup ref="verifyCreatedOrderInformation" stepKey="verifyCreatedOrderInformation"/> + + <after> + <actionGroup ref="logout" stepKey="logout"/> + + <deleteData createDataKey="simpleCustomer" stepKey="deleteSimpleCustomer"/> + + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + <deleteData createDataKey="createCategory" stepKey="deleteApiCategory"/> + </after> + </test> </tests> \ No newline at end of file diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminTaxReportGridTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminTaxReportGridTest.xml index 68fe8087c4fcd..05b85a3a55cb1 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminTaxReportGridTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminTaxReportGridTest.xml @@ -17,6 +17,9 @@ <severity value="MAJOR"/> <testCaseId value="MAGETWO-94338"/> <group value="Tax"/> + <skip> + <issueId value="MAGETWO-96193"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml index 3b741e7bf79ec..b87ab626d3970 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml @@ -17,6 +17,9 @@ <severity value="CRITICAL"/> <testCaseId value="MC-295"/> <group value="Tax"/> + <skip> + <issueId value="MAGETWO-96194"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From bd34b53918b3c159b5ceb87ac59f66c84f1b76ee Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Thu, 8 Nov 2018 10:48:18 +0300 Subject: [PATCH 706/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../view/adminhtml/web/js/grouped-product-grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index c06f615ae48e6..91454e8b3de78 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -114,7 +114,7 @@ define([ /** * - * @param {Array} recordData to reprocess + * @param {Array} - recordData to reprocess */ reloadGridData: function (recordData) { this.recordData(recordData.sort(function (a, b) { From c7a140ea0d878c43699d535b3c307ed2ffc5f7a0 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Thu, 8 Nov 2018 16:02:50 +0300 Subject: [PATCH 707/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../view/adminhtml/web/js/grouped-product-grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 91454e8b3de78..58c3b79022a62 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -114,7 +114,7 @@ define([ /** * - * @param {Array} - recordData to reprocess + * @param {Array} recordData - to reprocess */ reloadGridData: function (recordData) { this.recordData(recordData.sort(function (a, b) { From 50fb1cc2f50ac0b4e0c892ce474bc6c3b770cc7a Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Thu, 8 Nov 2018 15:25:05 +0200 Subject: [PATCH 708/812] MAGETWO-96063: [TSG] Pull Request MFTF 8 stabilization --- .../Test/Mftf/Page/AdminConfigPage.xml | 12 ++++ ...> AdminConfigAdvancedReportingSection.xml} | 7 +- .../AdminConfigurationBlankIndustryTest.xml | 15 ++-- ...onfigurationEnableDisableAnalyticsTest.xml | 35 +++++----- .../Test/AdminConfigurationIndustryTest.xml | 13 ++-- .../Test/AdminConfigurationPermissionTest.xml | 69 ++++++++++--------- .../AdminConfigurationTimeToSendDataTest.xml | 18 +++-- .../BraintreeCreditCardOnCheckoutTest.xml | 2 +- ...CategoryProductsUsingScopeSelectorTest.xml | 8 +-- ...efrontPurchaseProductWithCustomOptions.xml | 15 ++-- ...ctWithCustomOptionsWithLongValuesTitle.xml | 9 ++- .../ActionGroup/AdminCheckoutActionGroup.xml | 18 +++++ .../Mftf/ActionGroup/CheckoutActionGroup.xml | 14 +++- .../StorefrontProductCartActionGroup.xml | 4 +- .../Section/AdminCheckoutPaymentSection.xml | 14 ++++ .../Mftf/Section/CheckoutPaymentSection.xml | 2 +- ...StorefrontCheckoutPaymentMethodSection.xml | 15 ++++ .../Mftf/Test/StorefrontGuestCheckoutTest.xml | 1 + .../Test/Mftf/Section/AdminConfigSection.xml | 5 +- .../Test/Mftf/Test/AdminCreateInvoiceTest.xml | 1 + .../Mftf/Test/StorefrontTaxQuoteCartTest.xml | 4 ++ ...AssertBundleProductOnConfigureCartPage.php | 5 ++ .../app/Magento/Checkout/Test/Block/Cart.php | 17 +++++ .../Checkout/Test/Block/Cart/Shipping.php | 54 +++++++++++++++ .../Checkout/Test/Block/Cart/Totals.php | 11 +++ .../Constraint/AssertCartItemsOptions.php | 5 ++ .../AssertGrandTotalInShoppingCart.php | 4 ++ .../Constraint/AssertPriceInShoppingCart.php | 5 ++ .../AssertProductQtyInShoppingCart.php | 5 ++ .../AssertSubtotalInShoppingCart.php | 4 ++ .../Constraint/Utils/CartPageLoadTrait.php | 30 ++++++++ ...eProductFromMiniShoppingCartEntityTest.php | 1 + .../ProductsInCartReportEntityTest.php | 2 + ...oveShoppingCartProductsOnOrderPageTest.php | 1 + 34 files changed, 327 insertions(+), 98 deletions(-) create mode 100644 app/code/Magento/Analytics/Test/Mftf/Page/AdminConfigPage.xml rename app/code/Magento/Analytics/Test/Mftf/Section/{AdminConfigSection.xml => AdminConfigAdvancedReportingSection.xml} (86%) create mode 100644 app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminCheckoutActionGroup.xml create mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/AdminCheckoutPaymentSection.xml create mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutPaymentMethodSection.xml create mode 100644 dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/Utils/CartPageLoadTrait.php diff --git a/app/code/Magento/Analytics/Test/Mftf/Page/AdminConfigPage.xml b/app/code/Magento/Analytics/Test/Mftf/Page/AdminConfigPage.xml new file mode 100644 index 0000000000000..c4ced12e67e07 --- /dev/null +++ b/app/code/Magento/Analytics/Test/Mftf/Page/AdminConfigPage.xml @@ -0,0 +1,12 @@ +<?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="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="AdminConfigGeneralAnalyticsPage" url="admin/system_config/edit/section/analytics/" area="admin" module="Magento_Config"> + <section name="AdminConfigAdvancedReportingSection"/> + </page> +</pages> diff --git a/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml b/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigAdvancedReportingSection.xml similarity index 86% rename from app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml rename to app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigAdvancedReportingSection.xml index f8554a4ea115b..2e5f2b762a7b1 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigSection.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Section/AdminConfigAdvancedReportingSection.xml @@ -6,8 +6,8 @@ */ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="AdminConfigSection"> - <element name="advancedReportingMenuItem" type="text" selector="//*[@id='system_config_tabs']/div[1]//span[text()='Advanced Reporting']"/> + <section name="AdminConfigAdvancedReportingSection"> + <element name="advancedReportingMenuItem" type="text" selector="//*[@class='admin__page-nav-link item-nav']//span[text()='Advanced Reporting']"/> <element name="advancedReportingService" type="select" selector="#analytics_general_enabled"/> <element name="advancedReportingServiceLabel" type="text" selector="#row_analytics_general_enabled>td.label>label>span"/> <element name="advancedReportingServiceStatus" type="text" selector="#row_analytics_general_enabled>td.value>p>span"/> @@ -17,6 +17,5 @@ <element name="advancedReportingMinute" type="select" selector="#row_analytics_general_collection_time>td:nth-child(2)>select:nth-child(3)"/> <element name="advancedReportingSeconds" type="select" selector="#row_analytics_general_collection_time>td:nth-child(2)>select:nth-child(4)"/> <element name="advancedReportingBlankIndustryError" type="text" selector=".message-error>div"/> - <element name="advancedReportingSuccessMessage" type="text" selector=".message-success>div"/> </section> -</sections> \ No newline at end of file +</sections> diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationBlankIndustryTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationBlankIndustryTest.xml index ff89ca9b663ee..914cb59b64e4e 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationBlankIndustryTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationBlankIndustryTest.xml @@ -18,15 +18,14 @@ <group value="analytics"/> </annotations> <after> - <amOnPage stepKey="amOnLogoutPage" url="admin/admin/auth/logout/"/> + <actionGroup ref="logout" stepKey="logoutOfAdmin"/> </after> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> - <amOnPage stepKey="amOnAdminConfig" url="{{AdminConfigPage.url}}"/> - <waitForPageLoad stepKey="waitForAdminConfig"/> - <click stepKey="clickAdvancedReportingConfigMenu" selector="{{AdminConfigSection.advancedReportingMenuItem}}"/> - <see stepKey="seeAdvancedReportingIndustryLabel" selector="{{AdminConfigSection.advancedReportingIndustryLabel}}" userInput="Industry"/> - <selectOption stepKey="selectAdvancedReportingIndustry" selector="{{AdminConfigSection.advancedReportingIndustry}}" userInput="--Please Select--"/> - <click stepKey="clickSaveConfigButton" selector="{{AdminConfigSection.saveButton}}"/> - <see stepKey="seeBlankIndustryErrorMessage" selector="{{AdminConfigSection.advancedReportingBlankIndustryError}}" userInput="Please select an industry."/> + <amOnPage url="{{AdminConfigGeneralAnalyticsPage.url}}" stepKey="amOnAdminConfig"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Enable" stepKey="selectAdvancedReportingServiceEnabled"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustryLabel}}" userInput="Industry" stepKey="seeAdvancedReportingIndustryLabel"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustry}}" userInput="--Please Select--" stepKey="selectAdvancedReportingIndustry"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveConfigButton"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingBlankIndustryError}}" userInput="Please select an industry." stepKey="seeBlankIndustryErrorMessage"/> </test> </tests> diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml index 1706383fc7866..1c1a3b27b06af 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationEnableDisableAnalyticsTest.xml @@ -18,27 +18,24 @@ <group value="analytics"/> </annotations> <after> - <amOnPage stepKey="amOnLogoutPage" url="admin/admin/auth/logout/"/> + <actionGroup ref="logout" stepKey="logoutOfAdmin"/> </after> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> - <!--Goto admin stores configure page --> - <amOnPage stepKey="amOnAdminConfig" url="{{AdminConfigPage.url}}"/> - <!--Enable Advanced Reporting--> - <click stepKey="clickAdvancedReportingConfigMenu" selector="{{AdminConfigSection.advancedReportingMenuItem}}"/> - <see stepKey="seeAdvancedReportingServiceLabelEnabled" selector="{{AdminConfigSection.advancedReportingServiceLabel}}" userInput="Advanced Reporting Service"/> - <selectOption stepKey="selectAdvancedReportingServiceEnabled" selector="{{AdminConfigSection.advancedReportingService}}" userInput="Enable"/> - <see stepKey="seeAdvancedReportingIndustryLabel" selector="{{AdminConfigSection.advancedReportingIndustryLabel}}" userInput="Industry"/> - <selectOption stepKey="selectAdvancedReportingIndustry" selector="{{AdminConfigSection.advancedReportingIndustry}}" userInput="Apps and Games"/> - <click stepKey="clickSaveConfigButtonEnabled" selector="{{AdminConfigSection.saveButton}}"/> - <see stepKey="seeSaveConfigurationMessageEnabled" selector="{{AdminConfigSection.advancedReportingSuccessMessage}}" userInput="You saved the configuration."/> - <see stepKey="seeAdvancedReportingServiceEnabled" selector="{{AdminConfigSection.advancedReportingService}}" userInput="Enable"/> - <see stepKey="seeAdvancedReportingServiceStatusEnabled" selector="{{AdminConfigSection.advancedReportingServiceStatus}}" userInput="Subscription status: Pending"/> + <amOnPage url="{{AdminConfigGeneralAnalyticsPage.url}}" stepKey="amOnAdminConfig"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingServiceLabel}}" userInput="Advanced Reporting Service" stepKey="seeAdvancedReportingServiceLabelEnabled"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Enable" stepKey="selectAdvancedReportingServiceEnabled"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustryLabel}}" userInput="Industry" stepKey="seeAdvancedReportingIndustryLabel"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustry}}" userInput="Apps and Games" stepKey="selectAdvancedReportingIndustry"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveConfigButton1"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeSuccess"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Enable" stepKey="seeAdvancedReportingServiceEnabled"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingServiceStatus}}" userInput="Subscription status: Pending" stepKey="seeAdvancedReportingServiceStatusEnabled"/> <!--Disable Advanced Reporting--> - <see stepKey="seeAdvancedReportingServiceLabelDisabled" selector="{{AdminConfigSection.advancedReportingServiceLabel}}" userInput="Advanced Reporting Service"/> - <selectOption stepKey="selectAdvancedReportingServiceDisabled" selector="{{AdminConfigSection.advancedReportingService}}" userInput="Disable"/> - <click stepKey="clickSaveConfigButtonDisabled" selector="{{AdminConfigSection.saveButton}}"/> - <see stepKey="seeSaveConfigurationMessageDisabled" selector="{{AdminConfigSection.advancedReportingSuccessMessage}}" userInput="You saved the configuration."/> - <see stepKey="seeAdvancedReportingServiceDisabled" selector="{{AdminConfigSection.advancedReportingService}}" userInput="Disable"/> - <see stepKey="seeAdvancedReportingServiceStatusDisabled" selector="{{AdminConfigSection.advancedReportingServiceStatus}}" userInput="Subscription status: Disabled"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingServiceLabel}}" userInput="Advanced Reporting Service" stepKey="seeAdvancedReportingServiceLabelDisabled"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Disable" stepKey="selectAdvancedReportingServiceDisabled"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveConfigButton2"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeSuccess2"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Disable" stepKey="seeAdvancedReportingServiceDisabled"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingServiceStatus}}" userInput="Subscription status: Disabled" stepKey="seeAdvancedReportingServiceStatusDisabled"/> </test> </tests> diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml index dcfdca9e8edd7..bb682c4468012 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml @@ -20,12 +20,11 @@ </annotations> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> - - <amOnPage stepKey="amOnAdminConfig" url="{{AdminConfigPage.url}}"/> - <click stepKey="clickAdvancedReportingConfigMenu" selector="{{AdminConfigSection.advancedReportingMenuItem}}"/> - <see stepKey="seeAdvancedReportingIndustryLabel" selector="{{AdminConfigSection.advancedReportingIndustryLabel}}" userInput="Industry"/> - <selectOption stepKey="selectAdvancedReportingIndustry" selector="{{AdminConfigSection.advancedReportingIndustry}}" userInput="Apps and Games"/> - <click stepKey="clickSaveConfigButton" selector="{{AdminConfigSection.saveButton}}"/> - <see stepKey="seeIndustrySuccessMessage" selector="{{AdminConfigSection.advancedReportingSuccessMessage}}" userInput="You saved the configuration."/> + <amOnPage url="{{AdminConfigGeneralAnalyticsPage.url}}" stepKey="amOnAdminConfig"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Enable" stepKey="selectAdvancedReportingServiceEnabled"/> + <see selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustryLabel}}" userInput="Industry" stepKey="seeAdvancedReportingIndustryLabel"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustry}}" userInput="Apps and Games" stepKey="selectAdvancedReportingIndustry"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveConfigButton"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeSuccess"/> </test> </tests> diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml index 5414e9c2a5c18..58e809ec45c4a 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationPermissionTest.xml @@ -19,44 +19,47 @@ <group value="analytics"/> </annotations> <before> - <createData stepKey="noReportUserRole" entity="adminNoReportRole"/> - <createData stepKey="noReportUser" entity="adminNoReport"/> + <createData entity="adminNoReportRole" stepKey="noReportUserRole"/> + <createData entity="adminNoReport" stepKey="noReportUser"/> + <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> </before> <after> - <amOnPage stepKey="amOnLogoutPage" url="admin/admin/auth/logout/"/> + <actionGroup ref="logout" stepKey="logoutOfAdmin"/> </after> - <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> + <amOnPage url="{{AdminUsersPage.url}}" stepKey="amOnAdminUsersPage"/> + <fillField selector="{{AdminUserGridSection.usernameFilterTextField}}" userInput="$$noReportUser.username$$" stepKey="fillUsernameSearch"/> + <click selector="{{AdminUserGridSection.searchButton}}" stepKey="clickSearchButton"/> + <waitForPageLoad time="10" stepKey="wait1"/> + <see selector="{{AdminUserGridSection.usernameInFirstRow}}" userInput="$$noReportUser.username$$" stepKey="seeFoundUsername"/> + <click selector="{{AdminUserGridSection.searchResultFirstRow}}" stepKey="clickFoundUsername"/> + <waitForPageLoad time="30" stepKey="wait2"/> + <seeInField selector="{{AdminEditUserSection.usernameTextField}}" userInput="$$noReportUser.username$$" stepKey="seeUsernameInField"/> + <fillField selector="{{AdminEditUserSection.currentPasswordField}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}" stepKey="fillCurrentPassword"/> + <click selector="{{AdminEditUserSection.userRoleTab}}" stepKey="clickUserRoleTab"/> - <amOnPage stepKey="amOnAdminUsersPage" url="{{AdminUsersPage.url}}"/> - <fillField stepKey="fillUsernameSearch" selector="{{AdminUserGridSection.usernameFilterTextField}}" userInput="$$noReportUser.username$$"/> - <click stepKey="clickSearchButton" selector="{{AdminUserGridSection.searchButton}}"/> - <waitForPageLoad stepKey="wait1" time="10"/> - <see stepKey="seeFoundUsername" selector="{{AdminUserGridSection.usernameInFirstRow}}" userInput="$$noReportUser.username$$"/> - <click stepKey="clickFoundUsername" selector="{{AdminUserGridSection.searchResultFirstRow}}"/> - <waitForPageLoad stepKey="wait2" time="30"/> - <seeInField stepKey="seeUsernameInField" selector="{{AdminEditUserSection.usernameTextField}}" userInput="$$noReportUser.username$$"/> - <fillField stepKey="fillCurrentPassword" selector="{{AdminEditUserSection.currentPasswordField}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> - <click stepKey="clickUserRoleTab" selector="{{AdminEditUserSection.userRoleTab}}"/> + <fillField selector="{{AdminEditUserSection.roleNameFilterTextField}}" userInput="$$noReportUserRole.rolename$$" stepKey="fillRoleNameSearch"/> + <click selector="{{AdminEditUserSection.searchButton}}" stepKey="clickSearchButtonUserRole"/> + <waitForPageLoad time="10" stepKey="wait3"/> + <see selector="{{AdminEditUserSection.roleNameInFirstRow}}" userInput="$$noReportUserRole.rolename$$" stepKey="seeFoundRoleName"/> + <click selector="{{AdminEditUserSection.searchResultFirstRow}}" stepKey="clickFoundRoleName"/> + <click selector="{{AdminEditUserSection.saveButton}}" stepKey="clickSaveButton"/> + <waitForPageLoad time="10" stepKey="wait4"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the user." stepKey="seeSuccess"/> - <fillField stepKey="fillRoleNameSearch" selector="{{AdminEditUserSection.roleNameFilterTextField}}" userInput="$$noReportUserRole.rolename$$"/> - <click stepKey="clickSearchButtonUserRole" selector="{{AdminEditUserSection.searchButton}}"/> - <waitForPageLoad stepKey="wait3" time="10"/> - <see stepKey="seeFoundRoleName" selector="{{AdminEditUserSection.roleNameInFirstRow}}" userInput="$$noReportUserRole.rolename$$"/> - <click stepKey="clickFoundRoleName" selector="{{AdminEditUserSection.searchResultFirstRow}}"/> - <click stepKey="clickSaveButton" selector="{{AdminEditUserSection.saveButton}}"/> - <waitForPageLoad stepKey="wait4" time="10"/> - <see stepKey="saveUserSuccessMessage" selector="{{AdminUserGridSection.successMessage}}" userInput="You saved the user."/> + <amOnPage url="{{AdminConfigPage.url}}" stepKey="amOnAdminConfig"/> + <conditionalClick selector="{{AdminConfigSection.generalTab}}" dependentSelector="{{AdminConfigSection.generalTabOpened}}" visible="false" stepKey="openGeneralTabIfClosed"/> + <scrollTo selector="{{AdminConfigAdvancedReportingSection.advancedReportingMenuItem}}" stepKey="scrollToMenuItem"/> + <!--<see stepKey="seeAdvancedReportingConfigMenuItem" selector="{{AdminConfigAdvancedReportingSection.advancedReportingMenuItem}}" userInput="Advanced Reporting"/>--> + <seeElementInDOM selector="{{AdminConfigAdvancedReportingSection.advancedReportingMenuItem}}" stepKey="seeAdvancedReportingConfigMenuItem"/> + <actionGroup ref="logout" stepKey="logoutOfAdmin2"/> - <amOnPage stepKey="amOnAdminConfig" url="{{AdminConfigPage.url}}"/> - <see stepKey="seeAdvancedReportingConfigMenuItem" selector="{{AdminConfigSection.advancedReportingMenuItem}}" userInput="Advanced Reporting"/> - <amOnPage stepKey="amOnLogoutPage2" url="admin/admin/auth/logout/"/> - - <amOnPage stepKey="amOnAdminLoginPage" url="{{AdminLoginPage.url}}"/> - <fillField stepKey="fillUsernameNoReport" selector="{{AdminLoginFormSection.username}}" userInput="$$noReportUser.username$$"/> - <fillField stepKey="fillPasswordNoReport" selector="{{AdminLoginFormSection.password}}" userInput="$$noReportUser.password$$"/> - <click stepKey="clickOnSignIn2" selector="{{AdminLoginFormSection.signIn}}"/> - <waitForPageLoad stepKey="wait5" time="10"/> - <amOnPage stepKey="amOnAdminConfig2" url="{{AdminConfigPage.url}}"/> - <dontSee stepKey="dontSeeAdvancedReportingConfigMenuItem" selector="{{AdminConfigSection.advancedReportingMenuItem}}" userInput="Advanced Reporting"/> + <amOnPage url="{{AdminLoginPage.url}}" stepKey="amOnAdminLoginPage"/> + <fillField selector="{{AdminLoginFormSection.username}}" userInput="$$noReportUser.username$$" stepKey="fillUsernameNoReport"/> + <fillField selector="{{AdminLoginFormSection.password}}" userInput="$$noReportUser.password$$" stepKey="fillPasswordNoReport"/> + <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickOnSignIn2"/> + <waitForPageLoad time="10" stepKey="wait5"/> + <amOnPage url="{{AdminConfigPage.url}}" stepKey="amOnAdminConfig2"/> + <conditionalClick selector="{{AdminConfigSection.generalTab}}" dependentSelector="{{AdminConfigSection.generalTabOpened}}" visible="false" stepKey="openGeneralTabIfClosed2"/> + <dontSeeElementInDOM selector="{{AdminConfigAdvancedReportingSection.advancedReportingMenuItem}}" stepKey="dontSeeAdvancedReportingConfigMenuItem"/> </test> </tests> diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml index 3f17df108b50b..9dc967971f63a 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml @@ -19,17 +19,15 @@ <group value="analytics"/> </annotations> <after> - <amOnPage stepKey="amOnLogoutPage" url="admin/admin/auth/logout/"/> + <actionGroup ref="logout" stepKey="logoutOfAdmin"/> </after> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> - <amOnPage stepKey="amOnAdminConfig" url="{{AdminConfigPage.url}}"/> - <waitForPageLoad stepKey="waitForAdminConfig"/> - <click stepKey="clickAdvancedReportingConfigMenu" selector="{{AdminConfigSection.advancedReportingMenuItem}}"/> - <selectOption stepKey="selectAdvancedReportingIndustry" selector="{{AdminConfigSection.advancedReportingIndustry}}" userInput="Apps and Games"/> - <selectOption stepKey="selectAdvancedReportingHour" selector="{{AdminConfigSection.advancedReportingHour}}" userInput="11"/> - <selectOption stepKey="selectAdvancedReportingMinute" selector="{{AdminConfigSection.advancedReportingMinute}}" userInput="11"/> - <selectOption stepKey="selectAdvancedReportingSeconds" selector="{{AdminConfigSection.advancedReportingSeconds}}" userInput="00"/> - <click stepKey="clickSaveConfigButton" selector="{{AdminConfigSection.saveButton}}"/> - <see stepKey="seeBlankIndustryErrorMessage" selector="{{AdminConfigSection.advancedReportingSuccessMessage}}" userInput="You saved the configuration."/> + <amOnPage url="{{AdminConfigGeneralAnalyticsPage.url}}" stepKey="amOnAdminConfig"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustry}}" userInput="Apps and Games" stepKey="selectAdvancedReportingIndustry"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingHour}}" userInput="11" stepKey="selectAdvancedReportingHour"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingMinute}}" userInput="11" stepKey="selectAdvancedReportingMinute"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingSeconds}}" userInput="00" stepKey="selectAdvancedReportingSeconds"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveConfigButton"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeSuccess"/> </test> </tests> diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml b/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml index 114c79189101a..2b5d60bea24e1 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml @@ -65,7 +65,7 @@ <actionGroup ref="StorefrontFillCartDataActionGroup" stepKey="StorefrontFillCartDataActionGroup"/> <waitForPageLoad stepKey="waitForPageLoad4"/> <!--Place order--> - <click selector="{{BraintreeConfigurationPaymentSection.paymentMethodContainer}} {{CheckoutPaymentSection.placeOrder}}" + <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="PlaceOrder"/> <waitForPageLoad stepKey="waitForPageLoad5"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml index a4bd507d98f55..a748635ac9a53 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml @@ -129,8 +129,8 @@ <waitForPageLoad stepKey="waitForCategoryPageLoad1"/> <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewOption('Default Store View')}}" stepKey="clickStoreView"/> - <waitForElement selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" - stepKey="waitForModalAccept"/> + <waitForElementVisible selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" + stepKey="waitForPopup1"/> <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" stepKey="clickActionAccept"/> <waitForElementNotVisible selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" stepKey="waitForNotVisibleModalAccept"/> @@ -152,8 +152,8 @@ <waitForPageLoad stepKey="waitForCategoryPageLoad3"/> <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewOption('secondStoreView')}}" stepKey="clickStoreView1"/> - <waitForElement selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" - stepKey="waitForModalAccept1"/> + <waitForElementVisible selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" + stepKey="waitForPopup2"/> <click selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" stepKey="clickActionAccept1"/> <waitForElementNotVisible selector="{{AdminCategoryMainActionsSection.CategoryStoreViewModalAccept}}" diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptions.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptions.xml index 6b444f1f6663b..c845a27773170 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptions.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptions.xml @@ -103,12 +103,15 @@ <see selector="{{CheckoutPaymentSection.ProductOptionsActiveByProductItemName($createProduct.name$)}}" userInput="Jan 1, 2018" stepKey="seeProductOptionDateAndTimeInput" /> <see selector="{{CheckoutPaymentSection.ProductOptionsActiveByProductItemName($createProduct.name$)}}" userInput="1/1/18, 1:00 AM" stepKey="seeProductOptionDataInput" /> <see selector="{{CheckoutPaymentSection.ProductOptionsActiveByProductItemName($createProduct.name$)}}" userInput="1:00 AM" stepKey="seeProductOptionTimeInput" /> - + <!--Select shipping method--> + <actionGroup ref="CheckoutSelectFlatRateShippingMethodActionGroup" stepKey="selectFlatRateShippingMethod"/> + <waitForElement selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> - + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskAfterClickNext"/> + <!--Select payment method--> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectPaymentMethod"/> <!-- Place Order --> - - <waitForElement selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/> + <waitForElementVisible selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/> <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/> @@ -119,6 +122,7 @@ <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnOrdersPage"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter"/> <fillField selector="{{AdminOrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="fillOrderNum"/> <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearchOrderNum"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnSearch"/> @@ -141,6 +145,7 @@ <!-- Reorder and Checking the correctness of displayed custom options for user parameters on Order and correctness of displayed price Subtotal--> <click selector="{{AdminOrderDetailsMainActionsSection.reorder}}" stepKey="clickReorder"/> + <actionGroup ref="AdminCheckoutSelectCheckMoneyOrderBillingMethodActionGroup" stepKey="selectBillingMethod"/> <click selector="{{AdminOrderFormActionSection.SubmitOrder}}" stepKey="trySubmitOrder"/> <see selector="{{AdminOrderItemsOrderedSection.productNameOptions}}" userInput="{{ProductOptionField.title}}" stepKey="seeAdminOrderProductOptionField1" /> @@ -179,4 +184,4 @@ <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> </test> -</tests> \ No newline at end of file +</tests> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptionsWithLongValuesTitle.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptionsWithLongValuesTitle.xml index a03636e52ee97..fcdb92d71f1f8 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptionsWithLongValuesTitle.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptionsWithLongValuesTitle.xml @@ -71,11 +71,17 @@ <see selector="{{CheckoutPaymentSection.ProductOptionsActiveByProductItemName($$createProduct.name$$)}}" userInput="{{ProductOptionValueDropdownLongTitle1.title}}" stepKey="seeProductOptionValueDropdown1Input1"/> + <!--Select shipping method--> + + <actionGroup ref="CheckoutSelectFlatRateShippingMethodActionGroup" stepKey="selectFlatRateShippingMethod"/> + <waitForElement selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskAfterClickNext"/> <!-- Place Order --> - <waitForElement selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectPaymentMethod"/> + <waitForElementVisible selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/> <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/> @@ -86,6 +92,7 @@ <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnOrdersPage"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter"/> <fillField selector="{{AdminOrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="fillOrderNum"/> <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearchOrderNum"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnSearch"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminCheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminCheckoutActionGroup.xml new file mode 100644 index 0000000000000..a29564b2457a9 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminCheckoutActionGroup.xml @@ -0,0 +1,18 @@ +<?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="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <!-- Checkout select Check/Money billing method --> + <actionGroup name="AdminCheckoutSelectCheckMoneyOrderBillingMethodActionGroup"> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <conditionalClick selector="{{AdminCheckoutPaymentSection.checkBillingMethodByName('Check / Money order')}}" dependentSelector="{{AdminCheckoutPaymentSection.checkBillingMethodByName('Check / Money order')}}" visible="true" stepKey="selectCheckmoBillingMethod"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskAfterBillingMethodSelection"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index 41b1e0d811851..1d30fcaa752a9 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -8,6 +8,12 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <!-- Checkout select Flat Rate shipping method --> + <actionGroup name="CheckoutSelectFlatRateShippingMethodActionGroup"> + <conditionalClick selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('Flat Rate')}}" dependentSelector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('Flat Rate')}}" visible="true" stepKey="selectFlatRateShippingMethod"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskForNextButton"/> + </actionGroup> + <!-- Go to checkout from minicart --> <actionGroup name="GoToCheckoutFromMinicartActionGroup"> <wait stepKey="wait" time="10" /> @@ -180,8 +186,10 @@ <!-- Checkout select Check/Money Order payment --> <actionGroup name="CheckoutSelectCheckMoneyOrderPaymentActionGroup"> - <waitForElement selector="{{CheckoutPaymentSection.paymentSectionTitle}}" time="30" stepKey="waitForPaymentSectionLoaded"/> - <conditionalClick selector="{{CheckoutPaymentSection.checkMoneyOrderPayment}}" dependentSelector="{{CheckoutPaymentSection.billingAddress}}" visible="false" stepKey="clickCheckMoneyOrderPayment" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <conditionalClick selector="{{StorefrontCheckoutPaymentMethodSection.checkPaymentMethodByName('Check / Money order')}}" dependentSelector="{{StorefrontCheckoutPaymentMethodSection.checkPaymentMethodByName('Check / Money order')}}" visible="true" stepKey="selectCheckmoPaymentMethod"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskAfterPaymentMethodSelection"/> </actionGroup> <!-- Check billing address in checkout --> @@ -228,4 +236,4 @@ <see userInput="You are signed out" stepKey="signOut"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml index 4b5b250078ad4..d832b7941c9d7 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml @@ -84,6 +84,8 @@ <argument name="total"/> </arguments> <seeInCurrentUrl url="{{CheckoutCartPage.url}}" stepKey="assertUrl"/> + <waitForPageLoad stepKey="waitPageFullyLoaded"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <waitForText userInput="${{total}}" selector="{{CheckoutCartSummarySection.total}}" time="30" stepKey="waitForTotal"/> <see userInput="${{subtotal}}" selector="{{CheckoutCartSummarySection.subtotal}}" stepKey="assertSubtotal"/> <see userInput="${{shipping}}" selector="{{CheckoutCartSummarySection.shipping}}" stepKey="assertShipping"/> @@ -109,4 +111,4 @@ <fillField stepKey="fillZip" selector="{{CheckoutCartSummarySection.postcode}}" userInput="{{taxCode.zip}}"/> <waitForPageLoad stepKey="waitForFormUpdate"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/AdminCheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/AdminCheckoutPaymentSection.xml new file mode 100644 index 0000000000000..2b5dd512bc4e4 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Section/AdminCheckoutPaymentSection.xml @@ -0,0 +1,14 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminCheckoutPaymentSection"> + <element name="checkBillingMethodByName" type="radio" selector="//div[@id='order-billing_method']//dl[@class='admin__payment-methods']//dt//label[contains(., '{{methodName}}')]/..//input" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index 846b20ed225dd..4a74ac8d60609 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -27,7 +27,7 @@ <element name="cartItemsArea" type="button" selector="div.block.items-in-cart"/> <element name="cartItemsAreaActive" type="textarea" selector="div.block.items-in-cart.active"/> <element name="checkMoneyOrderPayment" type="radio" selector="input#checkmo.radio" timeout="30"/> - <element name="placeOrder" type="button" selector="button.action.primary.checkout" timeout="30"/> + <element name="placeOrder" type="button" selector=".payment-method._active button.action.primary.checkout" timeout="30"/> <element name="paymentSectionTitle" type="text" selector="//*[@id='checkout-payment-method-load']//div[text()='Payment Method']" /> <element name="orderSummarySubtotal" type="text" selector="//tr[@class='totals sub']//span[@class='price']" /> <element name="orderSummaryShippingTotal" type="text" selector="//tr[@class='totals shipping excl']//span[@class='price']" /> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutPaymentMethodSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutPaymentMethodSection.xml new file mode 100644 index 0000000000000..c06af54f030e7 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontCheckoutPaymentMethodSection.xml @@ -0,0 +1,15 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontCheckoutPaymentMethodSection"> + <element name="billingAddress" type="text" selector=".checkout-billing-address"/> + <element name="checkPaymentMethodByName" type="radio" selector="//div[@id='checkout-payment-method-load']//div[@class='payment-method']//label//span[contains(., '{{methodName}}')]/../..//input" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml index 02cc233acc7bc..f9533fd946f35 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml @@ -57,6 +57,7 @@ <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnOrdersPage"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter"/> <fillField selector="{{AdminOrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="fillOrderNum"/> <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearchOrderNum"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnSearch"/> diff --git a/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml b/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml index f4698b6865779..8a56c2777084e 100644 --- a/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml +++ b/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml @@ -8,5 +8,8 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminConfigSection"> <element name="saveButton" type="button" selector="#save"/> + <element name="generalTab" type="text" selector="//div[@class='admin__page-nav-title title _collapsible']//strong[text()='General']"/> + <element name="generalTabClosed" type="text" selector="//div[@class='admin__page-nav-title title _collapsible' and @aria-expanded='false' or @aria-expanded='0']//strong[text()='General']"/> + <element name="generalTabOpened" type="text" selector="//div[@class='admin__page-nav-title title _collapsible' and @aria-expanded='true' or @aria-expanded='1']//strong[text()='General']"/> </section> -</sections> \ No newline at end of file +</sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index 0032a6c987e82..24266b5bcfe9f 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -61,6 +61,7 @@ <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask3"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter"/> <fillField selector="{{AdminOrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="searchOrderNum"/> <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearch"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml index 3b741e7bf79ec..65cde53d144e7 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml @@ -92,6 +92,7 @@ <!-- Assert that taxes are applied correctly for NY --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForCart"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.30"/> @@ -208,6 +209,7 @@ <!-- Assert that taxes are applied correctly for NY --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForCart"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> <see stepKey="seeTax" selector="{{CheckoutPaymentSection.tax}}" userInput="$8.37"/> @@ -314,6 +316,7 @@ <!-- Assert that taxes are applied correctly for CA --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForCart"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> <see stepKey="seeTax3" selector="{{CheckoutPaymentSection.tax}}" userInput="$10.15"/> @@ -420,6 +423,7 @@ <!-- Assert that taxes are applied correctly for NY --> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForCart"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <!-- Assert that taxes are applied correctly for CA --> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductOnConfigureCartPage.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductOnConfigureCartPage.php index efa75981db7bf..b97a954a981b2 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductOnConfigureCartPage.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleProductOnConfigureCartPage.php @@ -8,6 +8,7 @@ use Magento\Bundle\Test\Fixture\BundleProduct; use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Checkout\Test\Constraint\Utils\CartPageLoadTrait; use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Page\CheckoutCart; use Magento\Mtf\Constraint\AbstractAssertForm; @@ -17,6 +18,8 @@ */ class AssertBundleProductOnConfigureCartPage extends AbstractAssertForm { + use CartPageLoadTrait; + /** * Check bundle product options correctly displayed on cart configuration page. * @@ -28,6 +31,8 @@ class AssertBundleProductOnConfigureCartPage extends AbstractAssertForm public function processAssert(CheckoutCart $checkoutCart, Cart $cart, CatalogProductView $catalogProductView) { $checkoutCart->open(); + $this->waitForCartPageLoaded($checkoutCart); + $sourceProducts = $cart->getDataFieldConfig('items')['source']; $products = $sourceProducts->getProducts(); foreach ($cart->getItems() as $key => $item) { diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php index b0e996355642a..bbe6fe293ab50 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php @@ -106,6 +106,13 @@ class Cart extends Block */ protected $cartItemClass = \Magento\Checkout\Test\Block\Cart\CartItem::class; + /** + * Locator for page with ajax loading state. + * + * @var string + */ + private $ajaxLoading = 'body.ajax-loading'; + /** * Wait for PayPal page is loaded. * @@ -273,4 +280,14 @@ public function waitForCheckoutButton() { $this->waitForElementVisible($this->inContextPaypalCheckoutButton); } + + /** + * Wait loading. + * + * @return void + */ + public function waitForLoader() + { + $this->waitForElementNotVisible($this->ajaxLoading); + } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Shipping.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Shipping.php index 10299486a08ce..3d293700db8c9 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Shipping.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Shipping.php @@ -72,6 +72,13 @@ class Shipping extends Form */ protected $commonShippingPriceSelector = '.totals.shipping .price'; + /** + * Estimate shipping and tax form locator. + * + * @var string + */ + private $estimateShippingForm = '#shipping-zip-form'; + /** * Open estimate shipping and tax form. * @@ -250,4 +257,51 @@ public function waitForCommonShippingPriceBlock() { $this->waitForElementVisible($this->commonShippingPriceSelector, Locator::SELECTOR_CSS); } + + /** + * Wait until estimation form to appear. + * + * @return void + */ + public function waitForEstimateShippingAndTaxForm() + { + $browser = $this->browser; + $selector = $this->estimateShippingForm; + + $browser->waitUntil( + function () use ($browser, $selector) { + $element = $browser->find($selector); + return $element->isPresent() ? true : null; + } + ); + } + + /** + * Wait for shipping method form. + * + * @return void + */ + public function waitForShippingMethodForm() + { + $browser = $this->browser; + $selector = $this->shippingMethodForm; + + $browser->waitUntil( + function () use ($browser, $selector) { + $element = $browser->find($selector); + return $element->isPresent() ? true : null; + } + ); + } + + /** + * Wait for summary block to be loaded. + * + * @return void + */ + public function waitForSummaryBlock() + { + $this->waitForEstimateShippingAndTaxForm(); + $this->waitForShippingMethodForm(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Totals.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Totals.php index fda29a2fe78fc..f632cdc3d7464 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Totals.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Totals.php @@ -264,4 +264,15 @@ public function waitForShippingPriceBlock() { $this->waitForElementVisible($this->shippingPriceBlockSelector, Locator::SELECTOR_CSS); } + + /** + * Wait for "Grand Total" row to appear. + * + * @return void + */ + public function waitForGrandTotal() + { + $this->waitForUpdatedTotals(); + $this->waitForElementVisible($this->grandTotal); + } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartItemsOptions.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartItemsOptions.php index 144e41dca0d92..b0ed9d358f93a 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartItemsOptions.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCartItemsOptions.php @@ -7,6 +7,7 @@ namespace Magento\Checkout\Test\Constraint; use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Checkout\Test\Constraint\Utils\CartPageLoadTrait; use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Fixture\Cart\Items; use Magento\Checkout\Test\Page\CheckoutCart; @@ -21,6 +22,8 @@ */ class AssertCartItemsOptions extends AbstractAssertForm { + use CartPageLoadTrait; + /** * Error message for verify options * @@ -44,6 +47,8 @@ class AssertCartItemsOptions extends AbstractAssertForm public function processAssert(CheckoutCart $checkoutCart, Cart $cart) { $checkoutCart->open(); + $this->waitForCartPageLoaded($checkoutCart); + /** @var Items $sourceProducts */ $sourceProducts = $cart->getDataFieldConfig('items')['source']; $products = $sourceProducts->getProducts(); diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalInShoppingCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalInShoppingCart.php index 9bedda350d065..432bbd4f2146e 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalInShoppingCart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalInShoppingCart.php @@ -6,6 +6,7 @@ namespace Magento\Checkout\Test\Constraint; +use Magento\Checkout\Test\Constraint\Utils\CartPageLoadTrait; use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Page\CheckoutCart; use Magento\Mtf\Constraint\AbstractConstraint; @@ -16,6 +17,8 @@ */ class AssertGrandTotalInShoppingCart extends AbstractConstraint { + use CartPageLoadTrait; + /** * Assert that grand total is equal to expected * @@ -28,6 +31,7 @@ public function processAssert(CheckoutCart $checkoutCart, Cart $cart, $requireRe { if ($requireReload) { $checkoutCart->open(); + $this->waitForCartPageLoaded($checkoutCart); $checkoutCart->getTotalsBlock()->waitForUpdatedTotals(); } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertPriceInShoppingCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertPriceInShoppingCart.php index 42c79c1280e38..88d4a3e8d35ba 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertPriceInShoppingCart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertPriceInShoppingCart.php @@ -7,6 +7,7 @@ namespace Magento\Checkout\Test\Constraint; use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Checkout\Test\Constraint\Utils\CartPageLoadTrait; use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Fixture\Cart\Items; use Magento\Checkout\Test\Page\CheckoutCart; @@ -19,6 +20,8 @@ */ class AssertPriceInShoppingCart extends AbstractAssertForm { + use CartPageLoadTrait; + /** * Assert that price in the shopping cart equals to expected price from data set * @@ -29,6 +32,8 @@ class AssertPriceInShoppingCart extends AbstractAssertForm public function processAssert(CheckoutCart $checkoutCart, Cart $cart) { $checkoutCart->open(); + $this->waitForCartPageLoaded($checkoutCart); + /** @var Items $sourceProducts */ $sourceProducts = $cart->getDataFieldConfig('items')['source']; $products = $sourceProducts->getProducts(); diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductQtyInShoppingCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductQtyInShoppingCart.php index 40eb41e127245..b80b4c85227c0 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductQtyInShoppingCart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductQtyInShoppingCart.php @@ -7,6 +7,7 @@ namespace Magento\Checkout\Test\Constraint; use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Checkout\Test\Constraint\Utils\CartPageLoadTrait; use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Fixture\Cart\Items; use Magento\Checkout\Test\Page\CheckoutCart; @@ -19,6 +20,8 @@ */ class AssertProductQtyInShoppingCart extends AbstractAssertForm { + use CartPageLoadTrait; + /** * Assert that quantity in the shopping cart is equals to expected quantity from data set * @@ -29,6 +32,8 @@ class AssertProductQtyInShoppingCart extends AbstractAssertForm public function processAssert(CheckoutCart $checkoutCart, Cart $cart) { $checkoutCart->open(); + $this->waitForCartPageLoaded($checkoutCart); + /** @var Items $sourceProducts */ $sourceProducts = $cart->getDataFieldConfig('items')['source']; $products = $sourceProducts->getProducts(); diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertSubtotalInShoppingCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertSubtotalInShoppingCart.php index 2ee9caa251a74..5e743e735d42f 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertSubtotalInShoppingCart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertSubtotalInShoppingCart.php @@ -7,6 +7,7 @@ namespace Magento\Checkout\Test\Constraint; use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Checkout\Test\Constraint\Utils\CartPageLoadTrait; use Magento\Checkout\Test\Fixture\Cart; use Magento\Checkout\Test\Fixture\Cart\Items; use Magento\Checkout\Test\Page\CheckoutCart; @@ -19,6 +20,8 @@ */ class AssertSubtotalInShoppingCart extends AbstractAssertForm { + use CartPageLoadTrait; + /** * Assert that subtotal total in the shopping cart is equals to expected total from data set * @@ -31,6 +34,7 @@ public function processAssert(CheckoutCart $checkoutCart, Cart $cart, $requireRe { if ($requireReload) { $checkoutCart->open(); + $this->waitForCartPageLoaded($checkoutCart); } /** @var Items $sourceProducts */ diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/Utils/CartPageLoadTrait.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/Utils/CartPageLoadTrait.php new file mode 100644 index 0000000000000..fa349554fa139 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/Utils/CartPageLoadTrait.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Checkout\Test\Constraint\Utils; + +use Magento\Checkout\Test\Page\CheckoutCart; + +/** + * Check if cart page is fully loaded. + */ +trait CartPageLoadTrait +{ + /** + * @param CheckoutCart $checkoutCart + * @return void + */ + public function waitForCartPageLoaded(CheckoutCart $checkoutCart) : void + { + $checkoutCart->getCartBlock()->waitForLoader(); + if (!$checkoutCart->getCartBlock()->cartIsEmpty()) { + $checkoutCart->getShippingBlock()->waitForSummaryBlock(); + $checkoutCart->getTotalsBlock()->waitForGrandTotal(); + } + } +} diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php index 5935a68c43c21..af267cfa30ec1 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php @@ -115,6 +115,7 @@ public function test( } else { $miniShoppingCart->getCartItem($newProduct)->clickEditItem(); $this->catalogProductView->getViewBlock()->addToCart($newProduct); + $this->catalogProductView->getMessagesBlock()->waitSuccessMessage(); } // Prepare data for asserts: $cart['data']['items'] = ['products' => [$newProduct]]; diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.php index 30e790f978c42..1a4cb787bf1c7 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductsInCartReportEntityTest.php @@ -102,10 +102,12 @@ public function test( $productUrl = $_ENV['app_frontend_url'] . $product->getUrlKey() . '.html'; $browser->open($productUrl); $this->catalogProductView->getViewBlock()->addToCart($product); + $this->catalogProductView->getMessagesBlock()->waitSuccessMessage(); if ($isGuest) { $this->objectManager->create(\Magento\Customer\Test\TestStep\LogoutCustomerOnFrontendStep::class)->run(); $browser->open($productUrl); $this->catalogProductView->getViewBlock()->addToCart($product); + $this->catalogProductView->getMessagesBlock()->waitSuccessMessage(); } } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.php index 2b0bd7178cdad..91b4f711700b5 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.php @@ -144,6 +144,7 @@ public function test(Customer $customer, $product) )->run(); $this->browser->open($_ENV['app_frontend_url'] . $product->getUrlKey() . '.html'); $this->catalogProductView->getViewBlock()->addToCart($product); + $this->catalogProductView->getMessagesBlock()->waitSuccessMessage(); //Steps $this->customerIndex->open(); From 7bedc1a87767a148468586906eb68f76fae84a94 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Thu, 8 Nov 2018 16:07:46 +0200 Subject: [PATCH 709/812] magento-engcom/magento2ce#2316: Skipped MFTF test --- .../Test/Mftf/Test/AdminConfigurationIndustryTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml index dcfdca9e8edd7..4b18fc7b98309 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationIndustryTest.xml @@ -17,6 +17,9 @@ <severity value="MAJOR"/> <testCaseId value="MAGETWO-63898"/> <group value="analytics"/> + <skip> + <issueId value="MAGETWO-96223"/> + </skip> </annotations> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> From 7b3a047c27dc072938f85f7f0c0561d56c7ffd7c Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Thu, 8 Nov 2018 16:12:44 +0200 Subject: [PATCH 710/812] MAGETWO-96063: [TSG] Pull Request MFTF 8 stabilization --- .../Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml index 9dc967971f63a..58e62500b8203 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml @@ -23,6 +23,7 @@ </after> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> <amOnPage url="{{AdminConfigGeneralAnalyticsPage.url}}" stepKey="amOnAdminConfig"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Enable" stepKey="selectAdvancedReportingServiceEnabled"/> <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustry}}" userInput="Apps and Games" stepKey="selectAdvancedReportingIndustry"/> <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingHour}}" userInput="11" stepKey="selectAdvancedReportingHour"/> <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingMinute}}" userInput="11" stepKey="selectAdvancedReportingMinute"/> From f9acb655f01565c58d1df26643b4446407c4eb0a Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 8 Nov 2018 15:18:58 +0100 Subject: [PATCH 711/812] Added a separate resolver for returning category products count --- app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php | 1 - .../Magento/CatalogGraphQl/Model/Resolver/Category/Products.php | 2 +- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php index f0cdab9498abb..e783c749fdc6e 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php +++ b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php @@ -52,7 +52,6 @@ public function hydrateCategory(Category $category, $basicFieldsOnly = false) : $categoryData = $category->getData(); } else { $categoryData = $this->dataObjectProcessor->buildOutputDataArray($category, CategoryInterface::class); - $categoryData['product_count'] = $category->getProductCount(); } $categoryData['id'] = $category->getId(); $categoryData['children'] = []; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php index 557c7e08ff432..59c21b6b0109d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php @@ -65,7 +65,7 @@ public function resolve( 'eq' => $value['id'] ] ]; - $searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args); + $searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args); $searchCriteria->setCurrentPage($args['currentPage']); $searchCriteria->setPageSize($args['pageSize']); $searchResult = $this->filterQuery->getResult($searchCriteria, $info); diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 5d62cb63f1662..7f31266ebf266 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -379,7 +379,7 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model level: Int @doc(description: "Indicates the depth of the category within the tree") created_at: String @doc(description: "Timestamp indicating when the category was created") updated_at: String @doc(description: "Timestamp indicating when the category was updated") - product_count: Int @doc(description: "The number of products in the category") + product_count: Int @doc(description: "The number of products in the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\ProductsCount") default_sort_by: String @doc(description: "The attribute to use for sorting") products( pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), From 9aacf0e0f9044c133786de725fbe5d926c0223d5 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 8 Nov 2018 15:29:11 +0100 Subject: [PATCH 712/812] Missing resolver added --- .../Model/Resolver/Category/Products.php | 2 +- .../Model/Resolver/Category/ProductsCount.php | 70 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Category/ProductsCount.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php index 59c21b6b0109d..557c7e08ff432 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php @@ -65,7 +65,7 @@ public function resolve( 'eq' => $value['id'] ] ]; - $searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args); + $searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args); $searchCriteria->setCurrentPage($args['currentPage']); $searchCriteria->setPageSize($args['pageSize']); $searchResult = $this->filterQuery->getResult($searchCriteria, $info); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/ProductsCount.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/ProductsCount.php new file mode 100644 index 0000000000000..397fd12b7e714 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/ProductsCount.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Category; + +use Magento\Catalog\Model\Category; +use Magento\Catalog\Model\Product\Visibility; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor\StockProcessor; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; + +/** + * Retrieves products count for a category + */ +class ProductsCount implements ResolverInterface +{ + /** + * @var Visibility + */ + private $catalogProductVisibility; + + /** + * @var StockProcessor + */ + private $stockProcessor; + + /** + * @var SearchCriteriaInterface + */ + private $searchCriteria; + + /** + * @param Visibility $catalogProductVisibility + * @param SearchCriteriaInterface $searchCriteria + * @param StockProcessor $stockProcessor + */ + public function __construct( + Visibility $catalogProductVisibility, + SearchCriteriaInterface $searchCriteria, + StockProcessor $stockProcessor + ) { + $this->catalogProductVisibility = $catalogProductVisibility; + $this->searchCriteria = $searchCriteria; + $this->stockProcessor = $stockProcessor; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + if (!isset($value['model'])) { + throw new GraphQlInputException(__('"model" value should be specified')); + } + /** @var Category $category */ + $category = $value['model']; + $productsCollection = $category->getProductCollection(); + $productsCollection->setVisibility($this->catalogProductVisibility->getVisibleInSiteIds()); + $productsCollection = $this->stockProcessor->process($productsCollection, $this->searchCriteria, []); + + return $productsCollection->getSize(); + } +} From c713b675dc4c473d9d001ec2ade980aeeaf254f3 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Thu, 8 Nov 2018 15:39:28 +0100 Subject: [PATCH 713/812] Added test for setting shipping methods as guest for a customer cart --- .../Quote/SetShippingMethodOnCartTest.php | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php index 932c8ac386c27..7e77284c6b220 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php @@ -161,7 +161,35 @@ public function testSetShippingMethodWithNonExistingAddress() $this->sendRequestWithToken($query); } - // TODO: TBD - add check for guest with attempt to set shipping method to the customer's shopping cart + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetShippingMethodByGuestToCustomerCart() + { + $shippingCarrierCode = 'flatrate'; + $shippingMethodCode = 'flatrate'; + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); + $shippingAddress = $this->quote->getShippingAddress(); + $shippingAddressId = $shippingAddress->getId(); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $shippingMethodCode, + $shippingCarrierCode, + $shippingAddressId + ); + + self::expectExceptionMessage( + "The current user cannot perform operations on cart \"$maskedQuoteId\"" + ); + + $this->graphQlQuery($query); + } /** * Generates query for setting the specified shipping method on cart From 9b853a7303093342c2a29a17f3029da4428f8839 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Mon, 5 Nov 2018 15:42:06 -0600 Subject: [PATCH 714/812] MAGETWO-95906: Sales rules sets default time using UTC timezone when left empty --- .../Page/AdminConfigurationStoresPage.xml | 3 + .../Mftf/Section/LocaleOptionsSection.xml | 15 +++ .../StorefrontProductCartActionGroup.xml | 2 +- .../Controller/Adminhtml/Promo/Quote/Save.php | 38 ++++++- ...inCreateCartPriceRuleEmptyFromDateTest.xml | 104 ++++++++++++++++++ 5 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Backend/Test/Mftf/Section/LocaleOptionsSection.xml create mode 100644 app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml diff --git a/app/code/Magento/Backend/Test/Mftf/Page/AdminConfigurationStoresPage.xml b/app/code/Magento/Backend/Test/Mftf/Page/AdminConfigurationStoresPage.xml index d1bf3c2cb2ed6..8afc2c5bbb32f 100644 --- a/app/code/Magento/Backend/Test/Mftf/Page/AdminConfigurationStoresPage.xml +++ b/app/code/Magento/Backend/Test/Mftf/Page/AdminConfigurationStoresPage.xml @@ -14,4 +14,7 @@ <page name="WebConfigurationPage" url="admin/system_config/edit/section/web/" area="admin" module="Backend"> <section name="WYSIWYGOptionsSection"/> </page> + <page name="GeneralConfigurationPage" url="admin/system_config/edit/section/general/" area="admin" module="Backend"> + <section name="LocaleOptionsSection"/> + </page> </pages> diff --git a/app/code/Magento/Backend/Test/Mftf/Section/LocaleOptionsSection.xml b/app/code/Magento/Backend/Test/Mftf/Section/LocaleOptionsSection.xml new file mode 100644 index 0000000000000..c50bf0664f9cb --- /dev/null +++ b/app/code/Magento/Backend/Test/Mftf/Section/LocaleOptionsSection.xml @@ -0,0 +1,15 @@ +<?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="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="LocaleOptionsSection"> + <element name="sectionHeader" type="text" selector="#general_locale-head"/> + <element name="timezone" type="select" selector="#general_locale_timezone"/> + </section> +</sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml index 4b5b250078ad4..1473618ceeb34 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml @@ -86,8 +86,8 @@ <seeInCurrentUrl url="{{CheckoutCartPage.url}}" stepKey="assertUrl"/> <waitForText userInput="${{total}}" selector="{{CheckoutCartSummarySection.total}}" time="30" stepKey="waitForTotal"/> <see userInput="${{subtotal}}" selector="{{CheckoutCartSummarySection.subtotal}}" stepKey="assertSubtotal"/> - <see userInput="${{shipping}}" selector="{{CheckoutCartSummarySection.shipping}}" stepKey="assertShipping"/> <see userInput="({{shippingMethod}})" selector="{{CheckoutCartSummarySection.shippingMethod}}" stepKey="assertShippingMethod"/> + <waitForText userInput="${{shipping}}" selector="{{CheckoutCartSummarySection.shipping}}" time="30" stepKey="assertShipping"/> <see userInput="${{total}}" selector="{{CheckoutCartSummarySection.total}}" stepKey="assertTotal"/> </actionGroup> diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php index a5b71130e70eb..388679e6d9eff 100644 --- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php +++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php @@ -6,8 +6,41 @@ */ namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote; -class Save extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote +use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; + +/** + * SalesRule save controller + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class Save extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote implements HttpPostActionInterface { + /** + * @var TimezoneInterface + */ + private $timezone; + + /** + * @param \Magento\Backend\App\Action\Context $context + * @param \Magento\Framework\Registry $coreRegistry + * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory + * @param \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter + * @param TimezoneInterface $timezone + */ + public function __construct( + \Magento\Backend\App\Action\Context $context, + \Magento\Framework\Registry $coreRegistry, + \Magento\Framework\App\Response\Http\FileFactory $fileFactory, + \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter, + TimezoneInterface $timezone = null + ) { + parent::__construct($context, $coreRegistry, $fileFactory, $dateFilter); + $this->timezone = $timezone ?? \Magento\Framework\App\ObjectManager::getInstance()->get( + TimezoneInterface::class + ); + } + /** * Promo quote save action * @@ -26,6 +59,9 @@ public function execute() ['request' => $this->getRequest()] ); $data = $this->getRequest()->getPostValue(); + if (empty($data['from_date'])) { + $data['from_date'] = $this->timezone->formatDate(); + } $filterValues = ['from_date' => $this->_dateFilter]; if ($this->getRequest()->getParam('to_date')) { diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml new file mode 100644 index 0000000000000..e6676dab4eb5e --- /dev/null +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml @@ -0,0 +1,104 @@ +<?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="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateCartPriceRuleEmptyFromDateTest"> + <annotations> + <features value="SalesRule"/> + <stories value="Create cart price rule"/> + <title value="Admin should be able to create a cart price rule with no starting date"/> + <description value="Admin should be able to create a cart price rule without specifying the from_date and it should be set with the current date"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-5299"/> + <group value="SalesRule"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="category"/> + <createData entity="SimpleProduct" stepKey="product"> + <requiredEntity createDataKey="category"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <!-- Delete the cart price rule we made during the test --> + <actionGroup ref="DeleteCartPriceRuleByName" stepKey="cleanUpRule"> + <argument name="ruleName" value="{{_defaultCoupon.code}}"/> + </actionGroup> + <deleteData createDataKey="category" stepKey="deleteCategory"/> + <deleteData createDataKey="product" stepKey="deleteProduct"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <!--Set timezone--> + <!--Set timezone so we need compare with the same timezone used in "generateDate" action--> + <amOnPage url="{{GeneralConfigurationPage.url}}" stepKey="goToGeneralConfig"/> + <waitForPageLoad stepKey="waitForConfigPage"/> + <wait stepKey="wait" time="10"/> + <conditionalClick selector="{{LocaleOptionsSection.sectionHeader}}" dependentSelector="{{LocaleOptionsSection.timezone}}" visible="false" stepKey="openLocaleSection"/> + <grabValueFrom selector="{{LocaleOptionsSection.timezone}}" stepKey="originalTimezone"/> + <selectOption selector="{{LocaleOptionsSection.timezone}}" userInput="America/Los_Angeles" stepKey="setTimezone"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="saveConfig"/> + + <!-- Create a cart price rule based on a coupon code --> + <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/> + <waitForPageLoad stepKey="waitForPriceList"/> + <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> + <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="fillRuleName"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> + <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectCustomerGroup"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="{{_defaultCoupon.code}}" stepKey="fillCouponCode"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="selectActionType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="5" stepKey="fillDiscountAmount"/> + <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> + + <!-- Verify initial successful save --> + <see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> + <fillField selector="{{AdminCartPriceRulesSection.filterByNameInput}}" userInput="{{_defaultCoupon.code}}" stepKey="filterByName"/> + <click selector="{{AdminCartPriceRulesSection.searchButton}}" stepKey="doFilter"/> + <see selector="{{AdminCartPriceRulesSection.nameColumns}}" userInput="{{_defaultCoupon.code}}" stepKey="seeRuleInResults"/> + + <!-- Verify further on the Rule's edit page --> + <click selector="{{AdminCartPriceRulesSection.rowContainingText(_defaultCoupon.code)}}" stepKey="goToEditRule"/> + <seeInField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{_defaultCoupon.code}}" stepKey="seeRuleName"/> + <seeOptionIsSelected selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="seeWebsites"/> + <seeOptionIsSelected selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="seeCouponType"/> + <seeInField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="{{_defaultCoupon.code}}" stepKey="seeCouponCode"/> + <generateDate date="now" format="m/j/Y" timezone="America/Los_Angeles" stepKey="today"/> + <seeInField selector="{{AdminCartPriceRulesFormSection.fromDate}}" userInput="$today" stepKey="seeCorrectFromDate"/> + <seeInField selector="{{AdminCartPriceRulesFormSection.toDate}}" userInput="" stepKey="seeEmptyToDate"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions2"/> + <seeOptionIsSelected selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="Fixed amount discount for whole cart" stepKey="seeActionType"/> + <seeInField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="5" stepKey="seeDiscountAmount"/> + + <!-- Spot check the storefront --> + <amOnPage url="$$product.custom_attributes[url_key]$$.html" stepKey="goToProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart"/> + <waitForPageLoad stepKey="waitForAddToCart"/> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> + <waitForPageLoad stepKey="waitForCartPage"/> + <actionGroup ref="StorefrontApplyCouponActionGroup" stepKey="applyCoupon"> + <argument name="coupon" value="_defaultCoupon"/> + </actionGroup> + <waitForPageLoad stepKey="waitForProductPageLoad2"/> + <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> + <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$5.00" stepKey="seeDiscountTotal"/> + + <!--Reset timezone--> + <amOnPage url="{{GeneralConfigurationPage.url}}" stepKey="goToGeneralConfigReset"/> + <waitForPageLoad stepKey="waitForConfigPageReset"/> + <conditionalClick selector="{{LocaleOptionsSection.sectionHeader}}" dependentSelector="{{LocaleOptionsSection.timezone}}" visible="false" stepKey="openLocaleSectionReset"/> + <selectOption selector="{{LocaleOptionsSection.timezone}}" userInput="$originalTimezone" stepKey="resetTimezone"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="saveConfigReset"/> + </test> +</tests> From 13f4ad193092a153338418024facef621e598468 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 8 Nov 2018 08:41:45 -0600 Subject: [PATCH 715/812] MAGETWO-96192: Products with "Less Than", "Greater Than", "Less Than Or Equal", "Greater Than Or Equal" condition returns error on storefront - Added < and > to list of encoded characters --- .../Cms/Test/Mftf/Section/TinyMCESection.xml | 3 +++ ...oWYSIWYGWithCatalogProductListTypeTest.xml | 23 ++++++++++++++++++- .../Framework/Data/Wysiwyg/Normalizer.php | 3 ++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml index 92112661846c0..c7ea85e441bb9 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection.xml @@ -98,6 +98,9 @@ <element name="AddParam" type="button" selector=".rule-param-add"/> <element name="ConditionsDropdown" type="select" selector="#conditions__1__new_child"/> <element name="RuleParam" type="button" selector="//a[text()='...']"/> + <element name="RuleParamSelect" type="select" selector="//ul[contains(@class,'rule-param-children')]/li[{{arg1}}]//*[contains(@class,'rule-param')][{{arg2}}]//select" parameterized="true"/> + <element name="RuleParamInput" type="input" selector="//ul[contains(@class,'rule-param-children')]/li[{{arg1}}]//*[contains(@class,'rule-param')][{{arg2}}]//input" parameterized="true"/> + <element name="RuleParamLabel" type="input" selector="//ul[contains(@class,'rule-param-children')]/li[{{arg1}}]//*[contains(@class,'rule-param')][{{arg2}}]//a" parameterized="true"/> <element name="Chooser" type="button" selector="//img[@title='Open Chooser']"/> <element name="PageSize" type="input" selector="input[name='parameters[page_size]']"/> <element name="ProductAttribute" type="multiselect" selector="select[name='parameters[show_attributes][]']" /> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest.xml index 705f2883f5839..2586ffc11d086 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeTest.xml @@ -57,8 +57,29 @@ <click selector="{{WidgetSection.RuleParam}}" stepKey="clickRuleParam" /> <waitForElementVisible selector="{{WidgetSection.Chooser}}" stepKey="waitForElement" /> <click selector="{{WidgetSection.Chooser}}" stepKey="clickChooser" /> - <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear3" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear4" /> <click selector="{{WidgetSection.PreCreateCategory('$$createPreReqCategory.name$$')}}" stepKey="selectPreCategory" /> + + <!-- Test that the "<" operand functions correctly --> + <click selector="{{WidgetSection.AddParam}}" stepKey="clickAddParamBtn2" /> + <waitForElementVisible selector="{{WidgetSection.ConditionsDropdown}}" stepKey="waitForDropdownVisible2"/> + <selectOption selector="{{WidgetSection.ConditionsDropdown}}" userInput="Price" stepKey="selectPriceCondition"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear3"/> + <click selector="{{WidgetSection.RuleParamLabel('2','1')}}" stepKey="clickOperatorLabel"/> + <selectOption selector="{{WidgetSection.RuleParamSelect('2','1')}}" userInput="<" stepKey="selectLessThanCondition"/> + <click selector="{{WidgetSection.RuleParam}}" stepKey="clickRuleParam2"/> + <fillField selector="{{WidgetSection.RuleParamInput('2','2')}}" userInput="125" stepKey="fillMaxPrice"/> + + <!-- Test that the ">" operand functions correctly --> + <click selector="{{WidgetSection.AddParam}}" stepKey="clickAddParamBtn3" /> + <waitForElementVisible selector="{{WidgetSection.ConditionsDropdown}}" stepKey="waitForDropdownVisible3"/> + <selectOption selector="{{WidgetSection.ConditionsDropdown}}" userInput="Price" stepKey="selectPriceCondition2"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear5"/> + <click selector="{{WidgetSection.RuleParamLabel('3','1')}}" stepKey="clickOperatorLabel2"/> + <selectOption selector="{{WidgetSection.RuleParamSelect('3','1')}}" userInput=">" stepKey="selectLessThanCondition2"/> + <click selector="{{WidgetSection.RuleParam}}" stepKey="clickRuleParam3"/> + <fillField selector="{{WidgetSection.RuleParamInput('3','2')}}" userInput="1" stepKey="fillMinPrice"/> + <click selector="{{WidgetSection.InsertWidget}}" stepKey="clickInsertWidget" /> <waitForPageLoad stepKey="wait6" /> <scrollTo selector="{{CmsNewPagePageSeoSection.header}}" stepKey="scrollToSearchEngineTab" /> diff --git a/lib/internal/Magento/Framework/Data/Wysiwyg/Normalizer.php b/lib/internal/Magento/Framework/Data/Wysiwyg/Normalizer.php index 62e7500a302a6..bbf10e9f574cf 100644 --- a/lib/internal/Magento/Framework/Data/Wysiwyg/Normalizer.php +++ b/lib/internal/Magento/Framework/Data/Wysiwyg/Normalizer.php @@ -10,12 +10,13 @@ */ class Normalizer { - const WYSIWYG_RESERVED_CHARACTERS_REPLACEMENT_MAP = [ '{' => '^[', '}' => '^]', '"' => '`', '\\' => '|', + '<' => '^(', + '>' => '^)' ]; /** From e5e7db172a906ae3baf94379d673db4856a78643 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Thu, 8 Nov 2018 17:48:37 +0300 Subject: [PATCH 716/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../view/adminhtml/web/js/grouped-product-grid.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 58c3b79022a62..28553eaa41d12 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -128,7 +128,7 @@ define([ * Event handler for "Send to bottom" button * * @param {Object} positionObj - * @return {boolean} + * @return {Boolean} */ sendToBottom: function (positionObj) { @@ -152,7 +152,7 @@ define([ * Event handler for "Send to top" button * * @param {Object} positionObj - * @returns {boolean} + * @return {Boolean} */ sendToTop: function (positionObj) { var objectToUpdate = this.getObjectToUpdate(positionObj), @@ -189,7 +189,7 @@ define([ * Value function for position input * * @param {Object} data - * @return {number} + * @return {Number} */ getCalculatedPosition: function (data) { return (~~this.currentPage() - 1) * this.pageSize + this.elems().pluck("name").indexOf(data.name); @@ -198,7 +198,7 @@ define([ /** * Return Page Boundary * - * @return {number} + * @return {Number} */ getDefaultPageBoundary: function () { return ~~this.currentPage() * this.pageSize - 1; @@ -207,7 +207,7 @@ define([ /** * Returns position for last element to be moved after * - * @return {number} + * @return {Number} */ getGlobalMaxPosition: function () { return _.max(this.recordData().map(function (r) { From 803cdb1a15c3f6736c3674a8eb24aa8713992e63 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Thu, 8 Nov 2018 09:23:21 -0600 Subject: [PATCH 717/812] ENGCOM-3408: #18956 Fixes for set root_category_id #18958 - fixed docblocks --- .../Model/Config/Importer/Processor/Create.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php index 71ffa5303293d..1fb9f1c224d3e 100644 --- a/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php +++ b/app/code/Magento/Store/Model/Config/Importer/Processor/Create.php @@ -17,8 +17,6 @@ /** * The processor for creating of new entities. - * - * {@inheritdoc} */ class Create implements ProcessorInterface { @@ -85,7 +83,9 @@ public function __construct( /** * Creates entities in application according to the data set. * - * {@inheritdoc} + * @param array $data The data to be processed + * @return void + * @throws RuntimeException If processor was unable to finish execution */ public function run(array $data) { @@ -230,8 +230,7 @@ private function createStores(array $items, array $data) } /** - * Searches through given websites and compares with current websites. - * Returns found website. + * Searches through given websites and compares with current websites and returns found website. * * @param array $data The data to be searched in * @param string $websiteId The website id @@ -253,8 +252,7 @@ private function detectWebsiteById(array $data, $websiteId) } /** - * Searches through given groups and compares with current websites. - * Returns found group. + * Searches through given groups and compares with current websites and returns found group. * * @param array $data The data to be searched in * @param string $groupId The group id @@ -276,8 +274,7 @@ private function detectGroupById(array $data, $groupId) } /** - * Searches through given stores and compares with current stores. - * Returns found store. + * Searches through given stores and compares with current stores and returns found store. * * @param array $data The data to be searched in * @param string $storeId The store id From 12d035d335e3d8903253cf00f155c35efb701df5 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 8 Nov 2018 13:29:50 -0600 Subject: [PATCH 718/812] MAGETWO-96192: Products with "Less Than", "Greater Than", "Less Than Or Equal", "Greater Than Or Equal" condition returns error on storefront - Updatd integration test --- .../Magento/Widget/Setup/LayoutUpdateConverterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Widget/Setup/LayoutUpdateConverterTest.php b/dev/tests/integration/testsuite/Magento/Widget/Setup/LayoutUpdateConverterTest.php index 43c0bd202cc92..3d43fb5a44575 100644 --- a/dev/tests/integration/testsuite/Magento/Widget/Setup/LayoutUpdateConverterTest.php +++ b/dev/tests/integration/testsuite/Magento/Widget/Setup/LayoutUpdateConverterTest.php @@ -34,7 +34,7 @@ public function convertDataProvider() // @codingStandardsIgnoreStart $beginning = '<body><referenceContainer name="content"><block class="Magento\CatalogWidget\Block\Product\ProductsList" name="23e38bbfa7cc6474454570e51aeffcc3" template="Magento_CatalogWidget::product/widget/content/grid.phtml"><action method="setData"><argument name="name" xsi:type="string">show_pager</argument><argument name="value" xsi:type="string">0</argument></action><action method="setData"><argument name="name" xsi:type="string">products_count</argument><argument name="value" xsi:type="string">10</argument></action><action method="setData">'; $serializedWidgetXml = '<argument name="name" xsi:type="string">conditions_encoded</argument><argument name="value" xsi:type="string">a:3:[i:1;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Combine`;s:10:`aggregator`;s:3:`all`;s:5:`value`;s:1:`1`;s:9:`new_child`;s:0:``;]s:4:`1--1`;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Product`;s:9:`attribute`;s:3:`sku`;s:8:`operator`;s:2:`()`;s:5:`value`;s:15:`simple, simple1`;]s:4:`1--2`;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Product`;s:9:`attribute`;s:5:`price`;s:8:`operator`;s:2:`<=`;s:5:`value`;s:2:`10`;]]</argument>'; - $jsonEncodedWidgetXml = '<argument name="name" xsi:type="string">conditions_encoded</argument><argument name="value" xsi:type="string">^[`1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,`aggregator`:`all`,`value`:`1`,`new_child`:``^],`1--1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`sku`,`operator`:`()`,`value`:`simple, simple1`^],`1--2`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`price`,`operator`:`<=`,`value`:`10`^]^]</argument>'; + $jsonEncodedWidgetXml = '<argument name="name" xsi:type="string">conditions_encoded</argument><argument name="value" xsi:type="string">^[`1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,`aggregator`:`all`,`value`:`1`,`new_child`:``^],`1--1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`sku`,`operator`:`()`,`value`:`simple, simple1`^],`1--2`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Product`,`attribute`:`price`,`operator`:`^(=`,`value`:`10`^]^]</argument>'; $ending = '</action><action method="setData"><argument name="name" xsi:type="string">page_var_name</argument><argument name="value" xsi:type="string">pobqks</argument></action></block></referenceContainer></body>'; // @codingStandardsIgnoreEnd return [ From 336f62c887b625cdec1a050a42aa19538eb51005 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Thu, 8 Nov 2018 19:07:56 -0600 Subject: [PATCH 719/812] MAGETWO-89232: Validation error appears if duplicate product twice - added functional test to cover the bug fix --- .../AdminProductGridActionGroup.xml | 7 ++++ .../Section/AdminProductFormActionSection.xml | 1 + .../AdminCreateProductDuplicateUrlkeyTest.xml | 42 +++++++++++++++++++ .../AdminSaveAndCloseActionGroup.xml | 6 +++ 4 files changed, 56 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml index 1bd9bb4a09c86..a077eced6d5d5 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml @@ -164,6 +164,13 @@ <waitForElementVisible selector="{{AdminProductGridConfirmActionSection.title}}" stepKey="waitForConfirmModal"/> <click selector="{{AdminProductGridConfirmActionSection.ok}}" stepKey="confirmProductDelete"/> </actionGroup> + <!--Delete all products by filtering grid and using mass delete action--> + <actionGroup name="deleteAllDuplicateProductUsingProductGrid" extends="deleteProductUsingProductGrid"> + <arguments> + <argument name="product"/> + </arguments> + <remove keyForRemoval="seeProductSkuInGrid"/> + </actionGroup> <!--Delete a product by filtering grid and using delete action--> <actionGroup name="deleteProductBySku"> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormActionSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormActionSection.xml index afbaba41a9bb7..c7d4cd16d788a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormActionSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormActionSection.xml @@ -15,5 +15,6 @@ <element name="saveAndClose" type="button" selector="span[title='Save & Close']" timeout="30"/> <element name="changeStoreButton" type="button" selector="#store-change-button" timeout="10"/> <element name="selectStoreView" type="button" selector="//ul[@data-role='stores-list']/li/a[normalize-space(.)='{{var1}}']" timeout="10" parameterized="true"/> + <element name="saveAndDuplicate" type="button" selector="span[id='save_and_duplicate']" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml index 95d74b9653113..8dffc3d352a7b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml @@ -40,4 +40,46 @@ <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> <see userInput="The value specified in the URL Key field would generate a URL that already exists" selector="{{AdminProductMessagesSection.errorMessage}}" stepKey="assertErrorMessage"/> </test> + <test name="AdminCreateProductDuplicateProductTest"> + <annotations> + <features value="Catalog"/> + <stories value="Errors"/> + <title value="No validation errors when trying to duplicate product twice"/> + <description value="No validation errors when trying to duplicate product twice"/> + <severity value="MAJOR"/> + <testCaseId value="MC-5472"/> + <group value="product"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + </before> + <after> + <!--Delete all products by filtering grid and using mass delete action--> + <actionGroup ref="deleteAllDuplicateProductUsingProductGrid" stepKey="deleteAllDuplicateProducts"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + <deleteData createDataKey="createCategory" stepKey="deletePreReqCatalog" /> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="searchForSimpleProduct1"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + <actionGroup ref="OpenEditProductOnBackendActionGroup" stepKey="openEditProduct1"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + <!--Save and duplicated the product once--> + <actionGroup ref="AdminFormSaveAndDuplicate" stepKey="saveAndDuplicateProductForm1"/> + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="searchForSimpleProduct2"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + <actionGroup ref="OpenEditProductOnBackendActionGroup" stepKey="openEditProduct2"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + <!--Save and duplicated the product second time--> + <actionGroup ref="AdminFormSaveAndDuplicate" stepKey="saveAndDuplicateProductForm2"/> + </test> </tests> diff --git a/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminSaveAndCloseActionGroup.xml b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminSaveAndCloseActionGroup.xml index 9a9458ab34d2b..20c8927d49171 100644 --- a/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminSaveAndCloseActionGroup.xml +++ b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminSaveAndCloseActionGroup.xml @@ -13,4 +13,10 @@ <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose"/> <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveMessageSuccess"/> </actionGroup> + <actionGroup name="AdminFormSaveAndDuplicate"> + <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="openSaveDropDown"/> + <click selector="{{AdminProductFormActionSection.saveAndDuplicate}}" stepKey="clickOnSaveAndDuplicate"/> + <see selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveSuccess" userInput="You saved the product."/> + <see selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertDuplicateSuccess" userInput="You duplicated the product."/> + </actionGroup> </actionGroups> From dc51f3e13799a46d8ea6204892c230d15e142b84 Mon Sep 17 00:00:00 2001 From: Alexandr Voronoy <servermed@gmail.com> Date: Fri, 9 Nov 2018 04:25:16 +0200 Subject: [PATCH 720/812] Missed PHPDoc argument headers in method --- .../framework/Magento/TestFramework/TestCase/GraphQlAbstract.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php index cfcd5dd1b51dd..9754a340900e2 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php @@ -33,6 +33,7 @@ abstract class GraphQlAbstract extends WebapiAbstract * @param string $query * @param array $variables * @param string $operationName + * @param array $headers * @return array|int|string|float|bool GraphQL call results * @throws \Exception */ From 15668ac2018ebfae033bd0cc18ded3e8628549ec Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Fri, 9 Nov 2018 12:30:37 +0300 Subject: [PATCH 721/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 28553eaa41d12..1ec11797e311f 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -170,6 +170,7 @@ define([ }); this.reloadGridData(recordData); } + return false; }, From 10e64f25fc69c35010a74cb5628e67a64e6f9256 Mon Sep 17 00:00:00 2001 From: Yevhenii Dumskyi <yevhenii.dumskyi@gmail.com> Date: Fri, 9 Nov 2018 12:16:37 +0200 Subject: [PATCH 722/812] Add save product with image integration test scenario --- .../Catalog/Model/ProductRepositoryTest.php | 48 +++++++++++++++++++ .../_files/product_simple_with_image.php | 45 +++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_image.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php index 39752460a1cd7..d4016b2bfa8d4 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php @@ -90,4 +90,52 @@ public function skuDataProvider(): array ['sku' => 'simple '], ]; } + + /** + * Test save product with gallery image + * + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_image.php + * + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\StateException + */ + public function testSaveProductWithGalleryImage(): void + { + /** @var $mediaConfig \Magento\Catalog\Model\Product\Media\Config */ + $mediaConfig = Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Model\Product\Media\Config::class); + + /** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */ + $mediaDirectory = Bootstrap::getObjectManager() + ->get(\Magento\Framework\Filesystem::class) + ->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA); + + $product = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); + $product->load(1); + + $path = $mediaConfig->getBaseMediaPath() . '/magento_image.jpg'; + $absolutePath = $mediaDirectory->getAbsolutePath() . $path; + $product->addImageToMediaGallery($absolutePath, [ + 'image', + 'small_image', + ], false, false); + + /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ + $productRepository = Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + $productRepository->save($product); + + $gallery = $product->getData('media_gallery'); + $this->assertArrayHasKey('images', $gallery); + $images = array_values($gallery['images']); + + $this->assertNotEmpty($gallery); + $this->assertTrue(isset($images[0]['file'])); + $this->assertStringStartsWith('/m/a/magento_image', $images[0]['file']); + $this->assertArrayHasKey('media_type', $images[0]); + $this->assertEquals('image', $images[0]['media_type']); + $this->assertStringStartsWith('/m/a/magento_image', $product->getData('image')); + $this->assertStringStartsWith('/m/a/magento_image', $product->getData('small_image')); + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_image.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_image.php new file mode 100644 index 0000000000000..252f99c97b787 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_image.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Catalog\Api\Data\ProductExtensionInterfaceFactory; +use Magento\Framework\App\Filesystem\DirectoryList; + +\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize(); + +/** @var \Magento\TestFramework\ObjectManager $objectManager */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = $objectManager->create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(1) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Simple Product') + ->setSku('simple') + ->setPrice(10) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED); + +/** @var $mediaConfig \Magento\Catalog\Model\Product\Media\Config */ +$mediaConfig = $objectManager->get(\Magento\Catalog\Model\Product\Media\Config::class); + +/** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */ +$mediaDirectory = $objectManager->get(\Magento\Framework\Filesystem::class) + ->getDirectoryWrite(DirectoryList::MEDIA); + +$targetDirPath = $mediaConfig->getBaseMediaPath(); +$targetTmpDirPath = $mediaConfig->getBaseTmpMediaPath(); + +$mediaDirectory->create($targetDirPath); +$mediaDirectory->create($targetTmpDirPath); + +$dist = $mediaDirectory->getAbsolutePath($mediaConfig->getBaseMediaPath() . DIRECTORY_SEPARATOR . 'magento_image.jpg'); +copy(__DIR__ . '/magento_image.jpg', $dist); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); +$productRepository->save($product); From 88b3e279455ffbcb5e901ab747dbd052bb851465 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Fri, 9 Nov 2018 13:33:57 +0300 Subject: [PATCH 723/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Fix static tests --- .../view/adminhtml/web/js/grouped-product-grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js index 1ec11797e311f..0ac3b58d6e3a7 100644 --- a/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js +++ b/app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product-grid.js @@ -193,7 +193,7 @@ define([ * @return {Number} */ getCalculatedPosition: function (data) { - return (~~this.currentPage() - 1) * this.pageSize + this.elems().pluck("name").indexOf(data.name); + return (~~this.currentPage() - 1) * this.pageSize + this.elems().pluck('name').indexOf(data.name); }, /** From fe7b9ac55097b64a023e607acacb1857f1926367 Mon Sep 17 00:00:00 2001 From: Vasilii Burlacu <v.burlacu@atwix.com> Date: Fri, 9 Nov 2018 13:48:17 +0200 Subject: [PATCH 724/812] magento/magento2:#19101 - API REST and Reserved Order Id - Fixed issue "Can not update cart with a reserved order number like 000000651" --- app/code/Magento/Quote/Api/Data/CartInterface.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Quote/Api/Data/CartInterface.php b/app/code/Magento/Quote/Api/Data/CartInterface.php index 551833e3effb1..b87869de6b3df 100644 --- a/app/code/Magento/Quote/Api/Data/CartInterface.php +++ b/app/code/Magento/Quote/Api/Data/CartInterface.php @@ -223,14 +223,14 @@ public function setBillingAddress(\Magento\Quote\Api\Data\AddressInterface $bill /** * Returns the reserved order ID for the cart. * - * @return int|null Reserved order ID. Otherwise, null. + * @return string|null Reserved order ID. Otherwise, null. */ public function getReservedOrderId(); /** * Sets the reserved order ID for the cart. * - * @param int $reservedOrderId + * @param string $reservedOrderId * @return $this */ public function setReservedOrderId($reservedOrderId); From e767121cab5385e1ea5f36b237622eb258333566 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Fri, 9 Nov 2018 15:54:57 +0300 Subject: [PATCH 725/812] MAGETWO-91650: Translation not working for product alerts - Add store id for product alert --- .../ProductAlert/etc/db_schema_whitelist.json | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json b/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json index 234e3d14876e5..94c9d07c85015 100644 --- a/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json +++ b/app/code/Magento/ProductAlert/etc/db_schema_whitelist.json @@ -1,6 +1,7 @@ { "product_alert_price": { "column": { + "store_id": true, "alert_price_id": true, "customer_id": true, "product_id": true, @@ -9,26 +10,26 @@ "add_date": true, "last_send_date": true, "send_count": true, - "status": true, - "store_id": true + "status": true }, "index": { + "PRODUCT_ALERT_PRICE_STORE_ID": true, "PRODUCT_ALERT_PRICE_CUSTOMER_ID": true, "PRODUCT_ALERT_PRICE_PRODUCT_ID": true, - "PRODUCT_ALERT_PRICE_WEBSITE_ID": true, - "PRODUCT_ALERT_PRICE_STORE_ID": true + "PRODUCT_ALERT_PRICE_WEBSITE_ID": true }, "constraint": { + "PRODUCT_ALERT_PRICE_STORE_ID_STORE_STORE_ID": true, "PRIMARY": true, "PRODUCT_ALERT_PRICE_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID": true, "PRODUCT_ALERT_PRICE_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID": true, "PRODUCT_ALERT_PRICE_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID": true, - "PRODUCT_ALERT_PRICE_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true, - "PRODUCT_ALERT_PRICE_STORE_ID_STORE_STORE_ID": true + "PRODUCT_ALERT_PRICE_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true } }, "product_alert_stock": { "column": { + "store_id": true, "alert_stock_id": true, "customer_id": true, "product_id": true, @@ -36,22 +37,21 @@ "add_date": true, "send_date": true, "send_count": true, - "status": true, - "store_id": true + "status": true }, "index": { + "PRODUCT_ALERT_STOCK_STORE_ID": true, "PRODUCT_ALERT_STOCK_CUSTOMER_ID": true, "PRODUCT_ALERT_STOCK_PRODUCT_ID": true, - "PRODUCT_ALERT_STOCK_WEBSITE_ID": true, - "PRODUCT_ALERT_STOCK_STORE_ID": true + "PRODUCT_ALERT_STOCK_WEBSITE_ID": true }, "constraint": { + "PRODUCT_ALERT_STOCK_STORE_ID_STORE_STORE_ID": true, "PRIMARY": true, "PRODUCT_ALERT_STOCK_WEBSITE_ID_STORE_WEBSITE_WEBSITE_ID": true, "PRODUCT_ALERT_STOCK_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID": true, "PRODUCT_ALERT_STOCK_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID": true, - "PRODUCT_ALERT_STOCK_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true, - "PRODUCT_ALERT_STOCK_STORE_ID_STORE_STORE_ID": true + "PRODUCT_ALERT_STOCK_PRODUCT_ID_SEQUENCE_PRODUCT_SEQUENCE_VALUE": true } } } From 842324af44d362b3533a4559e7d4c8ab35b2e2be Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Fri, 9 Nov 2018 15:02:27 +0200 Subject: [PATCH 726/812] magento-engcom/magento2ce#2324: Fixed Code Style Issues --- app/code/Magento/Backup/Controller/Adminhtml/Index.php | 5 ++++- .../Magento/Reports/Model/Product/Index/AbstractIndex.php | 7 ++++--- app/code/Magento/Weee/Model/Sales/Pdf/Weee.php | 2 ++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index.php b/app/code/Magento/Backup/Controller/Adminhtml/Index.php index 142211fe90a44..94dca327195f3 100644 --- a/app/code/Magento/Backup/Controller/Adminhtml/Index.php +++ b/app/code/Magento/Backup/Controller/Adminhtml/Index.php @@ -5,6 +5,9 @@ */ namespace Magento\Backup\Controller\Adminhtml; +use Magento\Backend\App\Action; +use Magento\Framework\App\Action\HttpGetActionInterface; + /** * Backup admin controller * @@ -12,7 +15,7 @@ * @api * @since 100.0.2 */ -abstract class Index extends \Magento\Backend\App\Action +abstract class Index extends Action implements HttpGetActionInterface { /** * Authorization level of a basic admin session diff --git a/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php b/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php index 56991e290dec6..7337286149cc3 100644 --- a/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php +++ b/app/code/Magento/Reports/Model/Product/Index/AbstractIndex.php @@ -113,7 +113,7 @@ public function beforeSave() /** * Retrieve visitor id * - * if don't exists return current visitor id + * If don't exists return current visitor id * * @return int */ @@ -128,7 +128,7 @@ public function getVisitorId() /** * Retrieve customer id * - * if customer don't logged in return null + * If customer don't logged in return null * * @return int */ @@ -143,7 +143,7 @@ public function getCustomerId() /** * Retrieve store id * - * default return current store id + * Default return current store id * * @return int */ @@ -246,6 +246,7 @@ public function clean() /** * Add product ids to current visitor/customer log + * * @param string[] $productIds * @return $this */ diff --git a/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php b/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php index 65480047f2f05..2b8c74581d973 100644 --- a/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php +++ b/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php @@ -36,6 +36,7 @@ public function __construct( /** * Check if weee total amount should be included * + * Example: * array( * $index => array( * 'amount' => $amount, @@ -43,6 +44,7 @@ public function __construct( * 'font_size'=> $font_size * ) * ) + * * @return array */ public function getTotalsForDisplay() From 40b2ebb83674897d81a2e98d309403ca7d5e75f1 Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Fri, 9 Nov 2018 18:15:52 +0400 Subject: [PATCH 727/812] MAGETWO-91633: Grouped Products: Associated Products Can't Be Sorted Between Pages - Updated element locator for test --- .../Mftf/Section/AdminProductFormGroupedProductsSection.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml index f5549f26bfd56..547c856d144c8 100644 --- a/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Section/AdminProductFormGroupedProductsSection.xml @@ -11,9 +11,9 @@ <section name="AdminProductFormGroupedProductsSection"> <element name="toggleGroupedProduct" type="button" selector="div[data-index=grouped] .admin__collapsible-title"/> <element name="addProductsToGroup" type="button" selector="button[data-index='grouped_products_button']" timeout="30"/> - <element name="nextActionButton" type="button" selector=".admin__field > .admin__field-control > .admin__control-table-pagination > .admin__data-grid-pager > .action-next"/> - <element name="previousActionButton" type="button" selector=".admin__field > .admin__field-control > .admin__control-table-pagination > .admin__data-grid-pager > .action-previous"/> + <element name="nextActionButton" type="button" selector="//*[@data-index='grouped']//*[@class='action-next']"/> + <element name="previousActionButton" type="button" selector="//*[@data-index='grouped']//*[@class='action-previous']"/> <element name="positionProduct" type="input" selector="//tbody/tr[{{arg}}][contains(@class,'data-row')]/td[10]//input[@class='position-widget-input']" parameterized="true"/> <element name="nameProductFromGrid" type="text" selector="//tbody/tr[{{arg}}][contains(@class,'data-row')]/td[4]//*[@class='admin__field-control']//span" parameterized="true"/> </section> -</sections> \ No newline at end of file +</sections> From e9f2b802a6127811867e193e3b792f7f8a0d1051 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 9 Nov 2018 09:44:47 -0600 Subject: [PATCH 728/812] MAGETWO-96231: All pages in magento are broken on Nginx (MAGE_DIRS errors) - Added check for array existence --- pub/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pub/index.php b/pub/index.php index 90b4778265447..612e190719053 100644 --- a/pub/index.php +++ b/pub/index.php @@ -26,7 +26,7 @@ $params = $_SERVER; $params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = array_replace_recursive( - $params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS], + $params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] ?? [], [ DirectoryList::PUB => [DirectoryList::URL_PATH => ''], DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'], From 6a20b98dd369a64ddfa6a08ea5e4f71ba94d8a50 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 9 Nov 2018 18:01:13 +0200 Subject: [PATCH 729/812] GraphQl-45: Product textarea field format -- Update benchmarks scenarios according to updated GraphQL Schema --- setup/performance-toolkit/benchmark.jmx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx index 37e07d1319572..a13fe47a86532 100644 --- a/setup/performance-toolkit/benchmark.jmx +++ b/setup/performance-toolkit/benchmark.jmx @@ -40763,7 +40763,7 @@ vars.put("configurable_sku", "Configurable Product - ${__time(YMD)}-${__threadNu <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(\n filter: {\n price: {gt: \"10\"}\n or: {\n sku:{like:\"%Product%\"}\n name:{like:\"%Configurable Product%\"}\n }\n }\n pageSize: 200\n currentPage: 1\n sort: {\n price: ASC\n name:DESC\n }\n ) {\n total_count\n items {\n attribute_set_id\n country_of_manufacture\n created_at\n description\n gift_message_available\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n \t... on PhysicalProductInterface {\n \tweight\n \t}\n }\n page_info {\n page_size\n current_page\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(\n filter: {\n price: {gt: \"10\"}\n or: {\n sku:{like:\"%Product%\"}\n name:{like:\"%Configurable Product%\"}\n }\n }\n pageSize: 200\n currentPage: 1\n sort: {\n price: ASC\n name:DESC\n }\n ) {\n total_count\n items {\n attribute_set_id\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n short_description {\n html\n }\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n \t... on PhysicalProductInterface {\n \tweight\n \t}\n }\n page_info {\n page_size\n current_page\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -40820,7 +40820,7 @@ vars.put("configurable_sku", "Configurable Product - ${__time(YMD)}-${__threadNu <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${simple_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${simple_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -40896,7 +40896,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: {eq:\"${configurable_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: {eq:\"${configurable_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -40965,7 +40965,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(\n search: \"configurable\"\n filter: {price: {gteq: \"1\"} }\n ) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(\n search: \"configurable\"\n filter: {price: {gteq: \"1\"} }\n ) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41025,7 +41025,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(search: \"configurable\") {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(search: \"configurable\") {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t\t}\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41085,7 +41085,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(search: \"color\") {\n filters {\n name\n filter_items_count\n request_var\n filter_items {\n label\n value_string\n items_count\n ... on SwatchLayerFilterItemInterface {\n swatch_data {\n type\n value\n }\n }\n }\n }\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n weight\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(search: \"color\") {\n filters {\n name\n filter_items_count\n request_var\n filter_items {\n label\n value_string\n items_count\n ... on SwatchLayerFilterItemInterface {\n swatch_data {\n type\n value\n }\n }\n }\n }\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n weight\n }\n ... on ConfigurableProduct {\n configurable_options {\n id\n attribute_id\n label\n position\n use_default\n attribute_code\n values {\n value_index\n label\n store_label\n default_label\n use_default_value\n }\n product_id\n }\n variants {\n product {\n ... on PhysicalProductInterface {\n weight\n }\n sku\n color\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n\n\n }\n attributes {\n label\n code\n value_index\n }\n }\n }\n }\n }\n}","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41145,7 +41145,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${bundle_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on BundleProduct {\n weight\n price_view\n dynamic_price\n dynamic_sku\n ship_bundle_items\n dynamic_weight\n items {\n option_id\n title\n required\n type\n position\n sku\n options {\n id\n qty\n position\n is_default\n price\n price_type\n can_change_quantity\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${bundle_product_sku}\"} }) {\n total_count\n items {\n ... on PhysicalProductInterface {\n weight\n }\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on BundleProduct {\n weight\n price_view\n dynamic_price\n dynamic_sku\n ship_bundle_items\n dynamic_weight\n items {\n option_id\n title\n required\n type\n position\n sku\n options {\n id\n qty\n position\n is_default\n price\n price_type\n can_change_quantity\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41214,7 +41214,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${downloadable_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n ... on DownloadableProduct {\n links_purchased_separately\n links_title\n downloadable_product_samples {\n id\n title\n sort_order\n sample_type\n sample_file\n sample_url\n }\n downloadable_product_links {\n id\n title\n sort_order\n is_shareable\n price\n number_of_downloads\n link_type\n sample_type\n sample_file\n sample_url\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${downloadable_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n ... on DownloadableProduct {\n links_purchased_separately\n links_title\n downloadable_product_samples {\n id\n title\n sort_order\n sample_type\n sample_file\n sample_url\n }\n downloadable_product_links {\n id\n title\n sort_order\n is_shareable\n price\n number_of_downloads\n link_type\n sample_type\n sample_file\n sample_url\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41301,7 +41301,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${virtual_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\n products(filter: {sku: { eq: \"${virtual_product_sku}\" } })\n {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on PhysicalProductInterface {\n \t\t\tweight\n \t\t }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> @@ -41368,7 +41368,7 @@ if (totalCount == null) { <collectionProp name="Arguments.arguments"> <elementProp name="" elementType="HTTPArgument"> <boolProp name="HTTPArgument.always_encode">false</boolProp> - <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${grouped_product_sku}\"} }) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on GroupedProduct {\n weight\n items {\n qty\n position\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> + <stringProp name="Argument.value">{"query":"{\nproducts(filter: {sku: {eq:\"${grouped_product_sku}\"} }) {\n total_count\n items {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n ... on GroupedProduct {\n weight\n items {\n qty\n position\n product {\n attribute_set_id\n categories\n {\n id\n position\n }\n country_of_manufacture\n created_at\n description {\n html\n }\n gift_message_available\n id\n image\n {\n url\n label\n }\n meta_description\n meta_keyword\n meta_title\n media_gallery_entries\n {\n disabled\n file\n id\n label\n media_type\n position\n types\n content\n {\n base64_encoded_data\n type\n name\n }\n video_content\n {\n media_type\n video_description\n video_metadata\n video_provider\n video_title\n video_url\n }\n }\n name\n new_from_date\n new_to_date\n options_container\n ... on CustomizableProductInterface {\n options\n {\n title\n required\n sort_order\n }\n }\n \n price {\n minimalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n maximalPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n regularPrice {\n amount {\n value\n currency\n }\n adjustments {\n amount {\n value\n currency\n }\n code\n description\n }\n }\n }\n product_links\n {\n link_type\n linked_product_sku\n linked_product_type\n position\n sku\n }\n short_description {\n html\n }\n sku\n small_image\n {\n url\n label\n }\n special_from_date\n special_price\n special_to_date\n swatch_image\n thumbnail\n {\n url\n label\n }\n tier_price\n tier_prices\n {\n customer_group_id\n percentage_value\n qty\n value\n website_id\n }\n type_id\n updated_at\n url_key\n url_path\n websites { id name code sort_order default_group_id is_default }\n }\n }\n }\n }\n }\n}\n","variables":null,"operationName":null}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> </collectionProp> From a9e86656de5a821497db3f046f127d3ca83dffa8 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Fri, 9 Nov 2018 10:11:19 -0600 Subject: [PATCH 730/812] MQE-1339: Bump MFTF version in Magento - Repulled origin lock file, updated MFTF in lock --- composer.lock | 156 +++++++++++++++++++++++++------------------------- 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/composer.lock b/composer.lock index 7a23eee0e178b..3565ab2420e05 100644 --- a/composer.lock +++ b/composer.lock @@ -257,16 +257,16 @@ }, { "name": "composer/composer", - "version": "1.7.3", + "version": "1.7.2", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7" + "reference": "576aab9b5abb2ed11a1c52353a759363216a4ad2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/e965b9aaa8854c3067f1ed2ae45f436572d73eb7", - "reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7", + "url": "https://api.github.com/repos/composer/composer/zipball/576aab9b5abb2ed11a1c52353a759363216a4ad2", + "reference": "576aab9b5abb2ed11a1c52353a759363216a4ad2", "shasum": "" }, "require": { @@ -333,7 +333,7 @@ "dependency", "package" ], - "time": "2018-11-01T09:05:06+00:00" + "time": "2018-08-16T14:57:12+00:00" }, { "name": "composer/semver", @@ -399,16 +399,16 @@ }, { "name": "composer/spdx-licenses", - "version": "1.5.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2" + "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7a9556b22bd9d4df7cad89876b00af58ef20d3a2", - "reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/cb17687e9f936acd7e7245ad3890f953770dec1b", + "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b", "shasum": "" }, "require": { @@ -456,7 +456,7 @@ "spdx", "validator" ], - "time": "2018-11-01T09:45:54+00:00" + "time": "2018-04-30T10:33:04+00:00" }, { "name": "composer/xdebug-handler", @@ -919,16 +919,16 @@ }, { "name": "monolog/monolog", - "version": "1.24.0", + "version": "1.23.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266" + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", - "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", "shasum": "" }, "require": { @@ -993,7 +993,7 @@ "logging", "psr-3" ], - "time": "2018-11-05T09:00:11+00:00" + "time": "2017-06-19T01:22:40+00:00" }, { "name": "oyejorge/less.php", @@ -1375,16 +1375,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.12", + "version": "2.0.11", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "8814dc7841db159daed0b32c2b08fb7e03c6afe7" + "reference": "7053f06f91b3de78e143d430e55a8f7889efc08b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/8814dc7841db159daed0b32c2b08fb7e03c6afe7", - "reference": "8814dc7841db159daed0b32c2b08fb7e03c6afe7", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7053f06f91b3de78e143d430e55a8f7889efc08b", + "reference": "7053f06f91b3de78e143d430e55a8f7889efc08b", "shasum": "" }, "require": { @@ -1463,7 +1463,7 @@ "x.509", "x509" ], - "time": "2018-11-04T05:45:48+00:00" + "time": "2018-04-15T16:55:05+00:00" }, { "name": "psr/container", @@ -1834,16 +1834,16 @@ }, { "name": "symfony/console", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "432122af37d8cd52fba1b294b11976e0d20df595" + "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/432122af37d8cd52fba1b294b11976e0d20df595", - "reference": "432122af37d8cd52fba1b294b11976e0d20df595", + "url": "https://api.github.com/repos/symfony/console/zipball/dc7122fe5f6113cfaba3b3de575d31112c9aa60b", + "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b", "shasum": "" }, "require": { @@ -1898,20 +1898,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:30:44+00:00" + "time": "2018-10-03T08:15:46+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "552541dad078c85d9414b09c041ede488b456cd5" + "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/552541dad078c85d9414b09c041ede488b456cd5", - "reference": "552541dad078c85d9414b09c041ede488b456cd5", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e", "shasum": "" }, "require": { @@ -1961,20 +1961,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-10-10T13:52:42+00:00" + "time": "2018-07-26T09:10:45+00:00" }, { "name": "symfony/filesystem", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981" + "reference": "596d12b40624055c300c8b619755b748ca5cf0b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/fd7bd6535beb1f0a0a9e3ee960666d0598546981", - "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/596d12b40624055c300c8b619755b748ca5cf0b5", + "reference": "596d12b40624055c300c8b619755b748ca5cf0b5", "shasum": "" }, "require": { @@ -2011,11 +2011,11 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-10-30T13:18:25+00:00" + "time": "2018-10-02T12:40:59+00:00" }, { "name": "symfony/finder", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -2064,7 +2064,7 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.10.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -2122,16 +2122,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.10.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", - "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", "shasum": "" }, "require": { @@ -2177,20 +2177,20 @@ "portable", "shim" ], - "time": "2018-09-21T13:07:52+00:00" + "time": "2018-08-06T14:22:27+00:00" }, { "name": "symfony/process", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "3e83acef94d979b1de946599ef86b3a352abcdc9" + "reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/3e83acef94d979b1de946599ef86b3a352abcdc9", - "reference": "3e83acef94d979b1de946599ef86b3a352abcdc9", + "url": "https://api.github.com/repos/symfony/process/zipball/ee33c0322a8fee0855afcc11fff81e6b1011b529", + "reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529", "shasum": "" }, "require": { @@ -2226,7 +2226,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-10-14T20:48:13+00:00" + "time": "2018-10-02T12:40:59+00:00" }, { "name": "tedivm/jshrink", @@ -8228,7 +8228,7 @@ }, { "name": "symfony/browser-kit", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", @@ -8285,16 +8285,16 @@ }, { "name": "symfony/config", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238" + "reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/991fec8bbe77367fc8b48ecbaa8a4bd6e905a238", - "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238", + "url": "https://api.github.com/repos/symfony/config/zipball/b3d4d7b567d7a49e6dfafb6d4760abc921177c96", + "reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96", "shasum": "" }, "require": { @@ -8344,11 +8344,11 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:09:42+00:00" + "time": "2018-09-08T13:24:10+00:00" }, { "name": "symfony/css-selector", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -8401,16 +8401,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "e72ee2c23d952e4c368ee98610fa22b79b89b483" + "reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e72ee2c23d952e4c368ee98610fa22b79b89b483", - "reference": "e72ee2c23d952e4c368ee98610fa22b79b89b483", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f6b9d893ad28aefd8942dc0469c8397e2216fe30", + "reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30", "shasum": "" }, "require": { @@ -8468,11 +8468,11 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-10-31T10:54:16+00:00" + "time": "2018-10-02T12:40:59+00:00" }, { "name": "symfony/dom-crawler", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", @@ -8529,16 +8529,16 @@ }, { "name": "symfony/http-foundation", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af" + "reference": "d528136617ff24f530e70df9605acc1b788b08d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/82d494c1492b0dd24bbc5c2d963fb02eb44491af", - "reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d528136617ff24f530e70df9605acc1b788b08d4", + "reference": "d528136617ff24f530e70df9605acc1b788b08d4", "shasum": "" }, "require": { @@ -8579,11 +8579,11 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:09:42+00:00" + "time": "2018-10-03T08:48:45+00:00" }, { "name": "symfony/options-resolver", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", @@ -8637,16 +8637,16 @@ }, { "name": "symfony/polyfill-php70", - "version": "v1.10.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224" + "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/6b88000cdd431cd2e940caa2cb569201f3f84224", - "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/1e24b0c4a56d55aaf368763a06c6d1c7d3194934", + "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934", "shasum": "" }, "require": { @@ -8692,20 +8692,20 @@ "portable", "shim" ], - "time": "2018-09-21T06:26:08+00:00" + "time": "2018-08-06T14:22:27+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.10.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" + "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", - "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/95c50420b0baed23852452a7f0c7b527303ed5ae", + "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae", "shasum": "" }, "require": { @@ -8747,11 +8747,11 @@ "portable", "shim" ], - "time": "2018-09-21T13:07:52+00:00" + "time": "2018-08-06T14:22:27+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.1.7", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", @@ -8800,7 +8800,7 @@ }, { "name": "symfony/yaml", - "version": "v3.4.18", + "version": "v3.4.17", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", From 45d3742f7a7a3104dc756350c854da18e02a6189 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 9 Nov 2018 18:50:33 +0200 Subject: [PATCH 731/812] GraphQl-45: Product textarea field format -- Update benchmarks scenarios according to updated GraphQL Schema --- .../Magento/GraphQl/Catalog/UrlRewritesTest.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php index c39b32e4bfa4f..43796d780646c 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php @@ -33,8 +33,10 @@ public function testProductWithNoCategoriesAssigned() items { name, sku, - description, - url_rewrites { + description { + html + } + url_rewrites { url, parameters { name, @@ -87,8 +89,10 @@ public function testProductWithOneCategoryAssigned() items { name, sku, - description, - url_rewrites { + description { + html + } + url_rewrites { url, parameters { name, From 6c8dfe2c4f2556a2c182f9042fab93ff0d5cc75d Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Fri, 9 Nov 2018 11:06:40 -0600 Subject: [PATCH 732/812] MAGETWO-89232: Validation error appears if duplicate product twice - CR comment --- .../Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml index 8dffc3d352a7b..6658ad36d7150 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml @@ -43,7 +43,7 @@ <test name="AdminCreateProductDuplicateProductTest"> <annotations> <features value="Catalog"/> - <stories value="Errors"/> + <stories value="Validation Errors"/> <title value="No validation errors when trying to duplicate product twice"/> <description value="No validation errors when trying to duplicate product twice"/> <severity value="MAJOR"/> From bfcf6249bb0e26d835e8bace4764c8cadfe1568b Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Fri, 9 Nov 2018 13:55:29 -0600 Subject: [PATCH 733/812] MQE-1339: Bump MFTF version in Magento - Fix flaky actionGroup --- .../ChangeStatusProductUsingProductGridActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml index 9698f9cef4219..1961b1002df70 100644 --- a/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml +++ b/app/code/Magento/Quote/Test/Mftf/ActionGroup/ChangeStatusProductUsingProductGridActionGroup.xml @@ -27,6 +27,7 @@ <click selector="{{AdminProductGridSection.changeStatus('status')}}" stepKey="clickChangeStatusDisabled"/> <waitForPageLoad stepKey="waitForDisable"/> <see selector="{{AdminMessagesSection.success}}" userInput="A total of 1 record(s) have been updated." stepKey="seeSuccessMessage"/> + <waitForLoadingMaskToDisappear stepKey="waitForMaskToDisappear"/> <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial2"/> </actionGroup> </actionGroups> From 15dc79bea4a604a22a68e3a14fbd643336b3a400 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Fri, 9 Nov 2018 16:04:29 -0600 Subject: [PATCH 734/812] ENGCOM-3421: Magento 2.3 Fix Notice and Exception while adding image to product programmatically #18952 - Fixed docblocks --- .../Magento/Catalog/Model/Product/Gallery/Processor.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index 9cd5073f4357c..0912324745360 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -88,6 +88,8 @@ public function __construct( } /** + * Return media_gallery attribute + * * @return \Magento\Catalog\Api\Data\ProductAttributeInterface * @since 101.0.0 */ @@ -383,7 +385,8 @@ public function setMediaAttribute(\Magento\Catalog\Model\Product $product, $medi } /** - * get media attribute codes + * Get media attribute codes + * * @return array * @since 101.0.0 */ @@ -393,6 +396,8 @@ public function getMediaAttributeCodes() } /** + * Trim .tmp ending from filename + * * @param string $file * @return string * @since 101.0.0 @@ -514,7 +519,6 @@ public function getAffectedFields($object) /** * Attribute value is not to be saved in a conventional way, separate table is used to store the complex value * - * {@inheritdoc} * @since 101.0.0 */ public function isScalar() From 5c04cf909f94d8a5afa1cb74dbaed5b0ccf8b955 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Fri, 9 Nov 2018 16:21:04 -0600 Subject: [PATCH 735/812] #2324: Skipping flaky test --- .../Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml index b87ab626d3970..0b2809dfc3543 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest.xml @@ -251,6 +251,9 @@ <severity value="CRITICAL"/> <testCaseId value="MC-297"/> <group value="Tax"/> + <skip> + <issueId value="MAGETWO-96266"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From e827b3220c12cc8e793e0486cd9425e4ca4c2853 Mon Sep 17 00:00:00 2001 From: Vova Yatsyuk <vova.yatsyuk@gmail.com> Date: Sat, 10 Nov 2018 11:43:05 +0200 Subject: [PATCH 736/812] Allow to read HTTP/2 response header. The issue is HTTP/2 sends the following headers `HTTP/2 200`, `HTTP/2 401` and so on. It doesn't have third parameter like HTTP/1.1 has: `HTTP/2 200 OK` --- lib/internal/Magento/Framework/HTTP/Client/Curl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/HTTP/Client/Curl.php b/lib/internal/Magento/Framework/HTTP/Client/Curl.php index d1dfafdeb2adb..0ac65a420ddcf 100644 --- a/lib/internal/Magento/Framework/HTTP/Client/Curl.php +++ b/lib/internal/Magento/Framework/HTTP/Client/Curl.php @@ -438,7 +438,7 @@ protected function parseHeaders($ch, $data) { if ($this->_headerCount == 0) { $line = explode(" ", trim($data), 3); - if (count($line) != 3) { + if (count($line) < 2) { $this->doError("Invalid response line returned from server: " . $data); } $this->_responseStatus = (int)$line[1]; From 57fcc1b24c4c582a96930ff7465e5f74417f2bcc Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Sat, 10 Nov 2018 11:46:07 +0200 Subject: [PATCH 737/812] =?UTF-8?q?magento/magento2#17833:=C2=A0=20Child?= =?UTF-8?q?=20theme=20does=20not=20inherit=20translations=20from=20parent?= =?UTF-8?q?=20theme=20-=20forward=20port=20unit=20tests=20from=202.2-devel?= =?UTF-8?q?op=20branch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Framework/Test/Unit/TranslateTest.php | 371 ++++++++++++++++++ lib/internal/Magento/Framework/Translate.php | 4 +- 2 files changed, 373 insertions(+), 2 deletions(-) create mode 100644 lib/internal/Magento/Framework/Test/Unit/TranslateTest.php diff --git a/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php b/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php new file mode 100644 index 0000000000000..6a6407c97a95f --- /dev/null +++ b/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php @@ -0,0 +1,371 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Test\Unit; + +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Framework\Translate; + +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class TranslateTest extends \PHPUnit\Framework\TestCase +{ + /** @var Translate */ + protected $translate; + + /** @var \Magento\Framework\View\DesignInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $viewDesign; + + /** @var \Magento\Framework\Cache\FrontendInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $cache; + + /** @var \Magento\Framework\View\FileSystem|\PHPUnit_Framework_MockObject_MockObject */ + protected $viewFileSystem; + + /** @var \Magento\Framework\Module\ModuleList|\PHPUnit_Framework_MockObject_MockObject */ + protected $moduleList; + + /** @var \Magento\Framework\Module\Dir\Reader|\PHPUnit_Framework_MockObject_MockObject */ + protected $modulesReader; + + /** @var \Magento\Framework\App\ScopeResolverInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $scopeResolver; + + /** @var \Magento\Framework\Translate\ResourceInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $resource; + + /** @var \Magento\Framework\Locale\ResolverInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $locale; + + /** @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject */ + protected $appState; + + /** @var \Magento\Framework\Filesystem|\PHPUnit_Framework_MockObject_MockObject */ + protected $filesystem; + + /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $request; + + /** @var \Magento\Framework\File\Csv|\PHPUnit_Framework_MockObject_MockObject */ + protected $csvParser; + + /** @var \Magento\Framework\App\Language\Dictionary|\PHPUnit_Framework_MockObject_MockObject */ + protected $packDictionary; + + /** @var \Magento\Framework\Filesystem\Directory\ReadInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $directory; + + /** @var \Magento\Framework\Filesystem\DriverInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $fileDriver; + + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->viewDesign = $this->createMock(\Magento\Framework\View\DesignInterface::class); + $this->cache = $this->createMock(\Magento\Framework\Cache\FrontendInterface::class); + $this->viewFileSystem = $this->createMock(\Magento\Framework\View\FileSystem::class); + $this->moduleList = $this->createMock(\Magento\Framework\Module\ModuleList::class); + $this->modulesReader = $this->createMock(\Magento\Framework\Module\Dir\Reader::class); + $this->scopeResolver = $this->createMock(\Magento\Framework\App\ScopeResolverInterface::class); + $this->resource = $this->createMock(\Magento\Framework\Translate\ResourceInterface::class); + $this->locale = $this->createMock(\Magento\Framework\Locale\ResolverInterface::class); + $this->appState = $this->createMock(\Magento\Framework\App\State::class); + $this->request = $this->getMockForAbstractClass( + \Magento\Framework\App\RequestInterface::class, + [], + '', + false, + false, + true, + ['getParam', 'getControllerModule'] + ); + $this->csvParser = $this->createMock(\Magento\Framework\File\Csv::class); + $this->packDictionary = $this->createMock(\Magento\Framework\App\Language\Dictionary::class); + $this->directory = $this->createMock(\Magento\Framework\Filesystem\Directory\ReadInterface::class); + $filesystem = $this->createMock(\Magento\Framework\Filesystem::class); + $filesystem->expects($this->once())->method('getDirectoryRead')->will($this->returnValue($this->directory)); + $this->fileDriver = $this->createMock(\Magento\Framework\Filesystem\DriverInterface::class); + + $this->translate = new Translate( + $this->viewDesign, + $this->cache, + $this->viewFileSystem, + $this->moduleList, + $this->modulesReader, + $this->scopeResolver, + $this->resource, + $this->locale, + $this->appState, + $filesystem, + $this->request, + $this->csvParser, + $this->packDictionary, + $this->fileDriver + ); + + $serializerMock = $this->createMock(SerializerInterface::class); + $serializerMock->method('serialize') + ->willReturnCallback(function ($data) { + return json_encode($data); + }); + $serializerMock->method('unserialize') + ->willReturnCallback(function ($string) { + return json_decode($string, true); + }); + $objectManager->setBackwardCompatibleProperty( + $this->translate, + 'serializer', + $serializerMock + ); + } + + /** + * @param string $area + * @param bool $forceReload + * @param array $cachedData + * @dataProvider dataProviderLoadDataCachedTranslation + */ + public function testLoadDataCachedTranslation($area, $forceReload, $cachedData) + { + $this->expectsSetConfig('Magento/luma'); + + $this->cache->expects($this->once()) + ->method('load') + ->will($this->returnValue(json_encode($cachedData))); + + $this->appState->expects($this->exactly($area ? 0 : 1)) + ->method('getAreaCode') + ->will($this->returnValue('frontend')); + + $this->translate->loadData($area, $forceReload); + $this->assertEquals($cachedData, $this->translate->getData()); + } + + /** + * @return array + */ + public function dataProviderLoadDataCachedTranslation() + { + $cachedData = ['cached 1' => 'translated 1', 'cached 2' => 'translated 2']; + return [ + ['adminhtml', false, $cachedData], + ['frontend', false, $cachedData], + [null, false, $cachedData], + ]; + } + + /** + * @param string $area + * @param bool $forceReload + * @dataProvider dataProviderForTestLoadData + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function testLoadData($area, $forceReload) + { + $this->expectsSetConfig('Magento/luma'); + + $this->appState->expects($this->exactly($area ? 0 : 1)) + ->method('getAreaCode') + ->will($this->returnValue('frontend')); + + $this->cache->expects($this->exactly($forceReload ? 0 : 1)) + ->method('load') + ->will($this->returnValue(false)); + + $this->directory->expects($this->any())->method('isExist')->will($this->returnValue(true)); + + // _loadModuleTranslation() + $modules = ['some_module', 'other_module', 'another_module', 'current_module']; + $this->request->expects($this->any()) + ->method('getControllerModule') + ->willReturn('current_module'); + $this->moduleList->expects($this->once())->method('getNames')->will($this->returnValue($modules)); + $moduleData = [ + 'module original' => 'module translated', + 'module theme' => 'module-theme original translated', + 'module pack' => 'module-pack original translated', + 'module db' => 'module-db original translated', + ]; + $this->modulesReader->expects($this->any())->method('getModuleDir')->will($this->returnValue('/app/module')); + $themeData = [ + 'theme original' => 'theme translated', + 'module theme' => 'theme translated overwrite', + 'module pack' => 'theme-pack translated overwrite', + 'module db' => 'theme-db translated overwrite', + ]; + $this->csvParser->expects($this->any()) + ->method('getDataPairs') + ->will( + $this->returnValueMap( + [ + ['/app/module/en_US.csv', 0, 1, $moduleData], + ['/app/module/en_GB.csv', 0, 1, $moduleData], + ['/theme.csv', 0, 1, $themeData], + ] + ) + ); + $this->fileDriver->expects($this->any()) + ->method('isExists') + ->will( + $this->returnValueMap( + [ + ['/app/module/en_US.csv', true], + ['/app/module/en_GB.csv', true], + ['/theme.csv', true], + ] + ) + ); + + // _loadPackTranslation + $packData = [ + 'pack original' => 'pack translated', + 'module pack' => 'pack translated overwrite', + 'module db' => 'pack-db translated overwrite', + ]; + $this->packDictionary->expects($this->once())->method('getDictionary')->will($this->returnValue($packData)); + + // _loadThemeTranslation() + $this->viewFileSystem->expects($this->any()) + ->method('getLocaleFileName') + ->will($this->returnValue('/theme.csv')); + + // _loadDbTranslation() + $dbData = [ + 'db original' => 'db translated', + 'module db' => 'db translated overwrite', + ]; + $this->resource->expects($this->any())->method('getTranslationArray')->will($this->returnValue($dbData)); + + $this->cache->expects($this->exactly($forceReload ? 0 : 1))->method('save'); + + $this->translate->loadData($area, $forceReload); + + $expected = [ + 'module original' => 'module translated', + 'module theme' => 'theme translated overwrite', + 'module pack' => 'theme-pack translated overwrite', + 'module db' => 'db translated overwrite', + 'theme original' => 'theme translated', + 'pack original' => 'pack translated', + 'db original' => 'db translated', + ]; + $this->assertEquals($expected, $this->translate->getData()); + } + + /** + * @return array + */ + public function dataProviderForTestLoadData() + { + return [ + ['adminhtml', true], + ['adminhtml', false], + ['frontend', true], + ['frontend', false], + [null, true], + [null, false] + ]; + } + + /** + * @param $data + * @param $result + * @dataProvider dataProviderForTestGetData + */ + public function testGetData($data, $result) + { + $this->cache->expects($this->once()) + ->method('load') + ->will($this->returnValue(json_encode($data))); + $this->expectsSetConfig('themeId'); + $this->translate->loadData('frontend'); + $this->assertEquals($result, $this->translate->getData()); + } + + /** + * @return array + */ + public function dataProviderForTestGetData() + { + $data = ['original 1' => 'translated 1', 'original 2' => 'translated 2']; + return [ + [$data, $data], + [null, []] + ]; + } + + public function testGetLocale() + { + $this->locale->expects($this->once())->method('getLocale')->will($this->returnValue('en_US')); + $this->assertEquals('en_US', $this->translate->getLocale()); + + $this->locale->expects($this->never())->method('getLocale'); + $this->assertEquals('en_US', $this->translate->getLocale()); + + $this->locale->expects($this->never())->method('getLocale'); + $this->translate->setLocale('en_GB'); + $this->assertEquals('en_GB', $this->translate->getLocale()); + } + + public function testSetLocale() + { + $this->translate->setLocale('en_GB'); + $this->locale->expects($this->never())->method('getLocale'); + $this->assertEquals('en_GB', $this->translate->getLocale()); + } + + public function testGetTheme() + { + $this->request->expects($this->at(0))->method('getParam')->with('theme')->will($this->returnValue('')); + + $requestTheme = ['theme_title' => 'Theme Title']; + $this->request->expects($this->at(1))->method('getParam')->with('theme') + ->will($this->returnValue($requestTheme)); + + $this->assertEquals('theme', $this->translate->getTheme()); + $this->assertEquals('themeTheme Title', $this->translate->getTheme()); + } + + public function testLoadDataNoTheme() + { + $forceReload = true; + $this->expectsSetConfig(null, null); + $this->moduleList->expects($this->once())->method('getNames')->will($this->returnValue([])); + $this->appState->expects($this->once())->method('getAreaCode')->will($this->returnValue('frontend')); + $this->packDictionary->expects($this->once())->method('getDictionary')->will($this->returnValue([])); + $this->resource->expects($this->any())->method('getTranslationArray')->will($this->returnValue([])); + $this->assertEquals($this->translate, $this->translate->loadData(null, $forceReload)); + } + + /** + * Declare calls expectation for setConfig() method + */ + protected function expectsSetConfig($themeId, $localeCode = 'en_US') + { + $this->locale->expects($this->any())->method('getLocale')->will($this->returnValue($localeCode)); + $scope = new \Magento\Framework\DataObject(['code' => 'frontendCode', 'id' => 1]); + $scopeAdmin = new \Magento\Framework\DataObject(['code' => 'adminCode', 'id' => 0]); + $this->scopeResolver->expects($this->any()) + ->method('getScope') + ->will( + $this->returnValueMap( + [ + [null, $scope], + ['admin', $scopeAdmin], + ] + ) + ); + $designTheme = $this->getMockBuilder(\Magento\Theme\Model\Theme::class) + ->disableOriginalConstructor() + ->getMock(); + + $designTheme->expects($this->once()) + ->method('getThemePath') + ->willReturn($themeId); + + $this->viewDesign->expects($this->any())->method('getDesignTheme')->will($this->returnValue($designTheme)); + } +} diff --git a/lib/internal/Magento/Framework/Translate.php b/lib/internal/Magento/Framework/Translate.php index ff1bf99162a8a..ce73338eee292 100644 --- a/lib/internal/Magento/Framework/Translate.php +++ b/lib/internal/Magento/Framework/Translate.php @@ -398,11 +398,11 @@ protected function _getModuleTranslationFile($moduleName, $locale) /** * Get theme translation locale file name * - * @param string $locale + * @param string|null $locale * @param array $config * @return string|null */ - private function getThemeTranslationFileName(string $locale, array $config): ?string + private function getThemeTranslationFileName(?string $locale, array $config): ?string { $fileName = $this->_viewFileSystem->getLocaleFileName( 'i18n' . '/' . $locale . '.csv', From fe73cf00549475b0ffc5a470e10ba4f1f3893b78 Mon Sep 17 00:00:00 2001 From: Vladyslav Podorozhnyi <v.podorozhnyi@ism-ukraine.com> Date: Sat, 10 Nov 2018 11:57:22 +0200 Subject: [PATCH 738/812] =?UTF-8?q?magento/magento2#17833:=C2=A0=20Child?= =?UTF-8?q?=20theme=20does=20not=20inherit=20translations=20from=20parent?= =?UTF-8?q?=20theme=20-=20forward=20port=20unit=20tests=20from=202.2-devel?= =?UTF-8?q?op=20branch=20-=20declare=20strict=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Framework/Test/Unit/TranslateTest.php | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php b/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php index 6a6407c97a95f..885be8557fa10 100644 --- a/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\Test\Unit; use Magento\Framework\Serialize\SerializerInterface; @@ -61,7 +63,7 @@ class TranslateTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Framework\Filesystem\DriverInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $fileDriver; - protected function setUp() + protected function setUp(): void { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->viewDesign = $this->createMock(\Magento\Framework\View\DesignInterface::class); @@ -128,7 +130,7 @@ protected function setUp() * @param array $cachedData * @dataProvider dataProviderLoadDataCachedTranslation */ - public function testLoadDataCachedTranslation($area, $forceReload, $cachedData) + public function testLoadDataCachedTranslation($area, $forceReload, $cachedData): void { $this->expectsSetConfig('Magento/luma'); @@ -147,7 +149,7 @@ public function testLoadDataCachedTranslation($area, $forceReload, $cachedData) /** * @return array */ - public function dataProviderLoadDataCachedTranslation() + public function dataProviderLoadDataCachedTranslation(): array { $cachedData = ['cached 1' => 'translated 1', 'cached 2' => 'translated 2']; return [ @@ -163,7 +165,7 @@ public function dataProviderLoadDataCachedTranslation() * @dataProvider dataProviderForTestLoadData * @SuppressWarnings(PHPMD.NPathComplexity) */ - public function testLoadData($area, $forceReload) + public function testLoadData($area, $forceReload): void { $this->expectsSetConfig('Magento/luma'); @@ -258,7 +260,7 @@ public function testLoadData($area, $forceReload) /** * @return array */ - public function dataProviderForTestLoadData() + public function dataProviderForTestLoadData(): array { return [ ['adminhtml', true], @@ -275,7 +277,7 @@ public function dataProviderForTestLoadData() * @param $result * @dataProvider dataProviderForTestGetData */ - public function testGetData($data, $result) + public function testGetData($data, $result): void { $this->cache->expects($this->once()) ->method('load') @@ -288,7 +290,7 @@ public function testGetData($data, $result) /** * @return array */ - public function dataProviderForTestGetData() + public function dataProviderForTestGetData(): array { $data = ['original 1' => 'translated 1', 'original 2' => 'translated 2']; return [ @@ -297,7 +299,7 @@ public function dataProviderForTestGetData() ]; } - public function testGetLocale() + public function testGetLocale(): void { $this->locale->expects($this->once())->method('getLocale')->will($this->returnValue('en_US')); $this->assertEquals('en_US', $this->translate->getLocale()); @@ -310,14 +312,14 @@ public function testGetLocale() $this->assertEquals('en_GB', $this->translate->getLocale()); } - public function testSetLocale() + public function testSetLocale(): void { $this->translate->setLocale('en_GB'); $this->locale->expects($this->never())->method('getLocale'); $this->assertEquals('en_GB', $this->translate->getLocale()); } - public function testGetTheme() + public function testGetTheme(): void { $this->request->expects($this->at(0))->method('getParam')->with('theme')->will($this->returnValue('')); @@ -329,7 +331,7 @@ public function testGetTheme() $this->assertEquals('themeTheme Title', $this->translate->getTheme()); } - public function testLoadDataNoTheme() + public function testLoadDataNoTheme(): void { $forceReload = true; $this->expectsSetConfig(null, null); @@ -343,7 +345,7 @@ public function testLoadDataNoTheme() /** * Declare calls expectation for setConfig() method */ - protected function expectsSetConfig($themeId, $localeCode = 'en_US') + protected function expectsSetConfig($themeId, $localeCode = 'en_US'): void { $this->locale->expects($this->any())->method('getLocale')->will($this->returnValue($localeCode)); $scope = new \Magento\Framework\DataObject(['code' => 'frontendCode', 'id' => 1]); From 284daec007cc9cc5bacc736e3d6ce00ebdf751ef Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 12 Nov 2018 15:00:28 +0200 Subject: [PATCH 739/812] magento/magento2#5929: [Forwardport] Saving Product does not update URL rewrite. --- ...ProductProcessUrlRewriteSavingObserver.php | 21 +++++++++++++++++-- ...uctProcessUrlRewriteSavingObserverTest.php | 3 +++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php index c4d67f447e2cf..6eda8dd0b61ee 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php @@ -6,11 +6,15 @@ namespace Magento\CatalogUrlRewrite\Observer; use Magento\Catalog\Model\Product; +use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator; use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; +use Magento\Framework\App\ObjectManager; use Magento\UrlRewrite\Model\UrlPersistInterface; -use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; use Magento\Framework\Event\ObserverInterface; +/** + * Class ProductProcessUrlRewriteSavingObserver + */ class ProductProcessUrlRewriteSavingObserver implements ObserverInterface { /** @@ -23,22 +27,33 @@ class ProductProcessUrlRewriteSavingObserver implements ObserverInterface */ private $urlPersist; + /** + * @var ProductUrlPathGenerator + */ + private $productUrlPathGenerator; + /** * @param ProductUrlRewriteGenerator $productUrlRewriteGenerator * @param UrlPersistInterface $urlPersist + * @param ProductUrlPathGenerator|null $productUrlPathGenerator */ public function __construct( ProductUrlRewriteGenerator $productUrlRewriteGenerator, - UrlPersistInterface $urlPersist + UrlPersistInterface $urlPersist, + ProductUrlPathGenerator $productUrlPathGenerator = null ) { $this->productUrlRewriteGenerator = $productUrlRewriteGenerator; $this->urlPersist = $urlPersist; + $this->productUrlPathGenerator = $productUrlPathGenerator ?: ObjectManager::getInstance() + ->get(ProductUrlPathGenerator::class); } /** * Generate urls for UrlRewrite and save it in storage + * * @param \Magento\Framework\Event\Observer $observer * @return void + * @throws \Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException */ public function execute(\Magento\Framework\Event\Observer $observer) { @@ -51,6 +66,8 @@ public function execute(\Magento\Framework\Event\Observer $observer) || $product->dataHasChangedFor('visibility') ) { if ($product->isVisibleInSiteVisibility()) { + $product->unsUrlPath(); + $product->setUrlPath($this->productUrlPathGenerator->getUrlPath($product)); $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product)); } } diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php index 9de0588356c43..c72a58197b1fd 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php @@ -90,6 +90,7 @@ public function testUrlKeyHasChangedInGlobalContext() $product->setData('save_rewrites_history', true); $product->setUrlKey('new-url'); + $product->setUrlPath('new-path'); $product->save(); $expected = [ @@ -152,6 +153,7 @@ public function testUrlKeyHasChangedInStoreviewContextWithPermanentRedirection() $product->setData('save_rewrites_history', true); $product->setUrlKey('new-url'); + $product->setUrlPath('new-path'); $product->save(); $expected = [ @@ -207,6 +209,7 @@ public function testUrlKeyHasChangedInStoreviewContextWithoutPermanentRedirectio $product->setData('save_rewrites_history', false); $product->setUrlKey('new-url'); + $product->setUrlPath('new-path'); $product->save(); $expected = [ From 63922949f0a1a2d018900672968cd8714a901db7 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 12 Nov 2018 15:01:50 +0200 Subject: [PATCH 740/812] GraphQl-28: Implement query complexity limiting --- app/code/Magento/GraphQl/etc/di.xml | 2 +- .../Framework/GraphQl/Query/QueryComplexityLimiter.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 622888f697b84..914dcc78e49e1 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -100,7 +100,7 @@ <type name="Magento\Framework\GraphQl\Query\QueryComplexityLimiter"> <arguments> <argument name="queryDepth" xsi:type="number">20</argument> - <argument name="queryComplexity" xsi:type="number">160</argument> + <argument name="queryComplexity" xsi:type="number">250</argument> </arguments> </type> </config> diff --git a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php index 3936da21fc56a..5730156ca5b34 100644 --- a/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php +++ b/lib/internal/Magento/Framework/GraphQl/Query/QueryComplexityLimiter.php @@ -38,8 +38,8 @@ class QueryComplexityLimiter * @param int $queryComplexity */ public function __construct( - int $queryDepth = 20, - int $queryComplexity = 160 + int $queryDepth, + int $queryComplexity ) { $this->queryDepth = $queryDepth; $this->queryComplexity = $queryComplexity; From f0dedde4c6fa32c84579928d48d613cf65684eca Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 12 Nov 2018 15:59:02 +0200 Subject: [PATCH 741/812] GraphQl-41: [Query] My Account > My Orders --- .../SalesGraphQl/Model/Resolver/Orders.php | 98 ++++++------ app/code/Magento/SalesGraphQl/composer.json | 3 + .../Magento/GraphQl/Sales/OrdersTest.php | 133 ++++++++-------- .../Sales/_files/orders_with_customer.php | 148 +++++++++--------- 4 files changed, 188 insertions(+), 194 deletions(-) diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php index 05af6829de454..f058ce9ae3bdd 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php @@ -7,70 +7,66 @@ namespace Magento\SalesGraphQl\Model\Resolver; -use Magento\Authorization\Model\UserContextInterface; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Sales\Model\ResourceModel\Order\CollectionFactoryInterface; -use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccountInterface; +use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccount; /** - * Class Orders + * Orders data reslover */ class Orders implements ResolverInterface { - /** - * @var CollectionFactoryInterface - */ - private $collectionFactory; + /** + * @var CollectionFactoryInterface + */ + private $collectionFactory; - /** - * @var CheckCustomerAccountInterface - */ - private $checkCustomerAccount; + /** + * @var CheckCustomerAccount + */ + private $checkCustomerAccount; - /** - * Orders constructor. - * @param CollectionFactoryInterface $collectionFactory - * @param CheckCustomerAccountInterface $checkCustomerAccount - */ - public function __construct( - CollectionFactoryInterface $collectionFactory, - CheckCustomerAccountInterface $checkCustomerAccount - ) { - $this->collectionFactory = $collectionFactory; - $this->checkCustomerAccount = $checkCustomerAccount; + /** + * @param CollectionFactoryInterface $collectionFactory + * @param CheckCustomerAccount $checkCustomerAccount + */ + public function __construct( + CollectionFactoryInterface $collectionFactory, + CheckCustomerAccount $checkCustomerAccount + ) { + $this->collectionFactory = $collectionFactory; + $this->checkCustomerAccount = $checkCustomerAccount; - } + } - /** - * {@inheritdoc} - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ) { - $customerId = $context->getUserId(); + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + $customerId = $context->getUserId(); + $this->checkCustomerAccount->execute($customerId, $context->getUserType()); - $this->checkCustomerAccount->execute($customerId, $context->getUserType()); + $items = []; + $orders = $this->collectionFactory->create($customerId); - $items = []; - $orders = $this->collectionFactory->create($customerId); - - /** @var \Magento\Sales\Model\Order $order */ - foreach ($orders as $order) { - $items[] = [ - 'id' => $order->getId(), - 'increment_id' => $order->getIncrementId(), - 'created_at' => $order->getCreatedAt(), - 'grand_total' => $order->getGrandTotal(), - 'status' => $order->getStatus() - ]; - } - - return ['items' => $items]; - } + /** @var \Magento\Sales\Model\Order $order */ + foreach ($orders as $order) { + $items[] = [ + 'id' => $order->getId(), + 'increment_id' => $order->getIncrementId(), + 'created_at' => $order->getCreatedAt(), + 'grand_total' => $order->getGrandTotal(), + 'status' => $order->getStatus(), + ]; + } + return ['items' => $items]; + } } diff --git a/app/code/Magento/SalesGraphQl/composer.json b/app/code/Magento/SalesGraphQl/composer.json index b75e18c7b7a97..3e29adbe7009e 100644 --- a/app/code/Magento/SalesGraphQl/composer.json +++ b/app/code/Magento/SalesGraphQl/composer.json @@ -5,8 +5,11 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/framework": "*", + "magento/module-authorization": "*", "magento/module-customer": "*", + "magento/module-customer-graph-ql": "*", "magento/module-catalog": "*", + "magento/module-sales": "*", "magento/module-store": "*" }, "suggest": { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php index 33620f6e55386..589b0bc7746f8 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/OrdersTest.php @@ -16,93 +16,88 @@ */ class OrdersTest extends GraphQlAbstract { - /** - * @var CustomerTokenServiceInterface - */ - private $customerTokenService; + /** + * @var CustomerTokenServiceInterface + */ + private $customerTokenService; - /** - * {@inheritdoc} - */ protected function setUp() { parent::setUp(); - $objectManager = Bootstrap::getObjectManager(); - $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + $this->customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class); } - /** - * @magentoApiDataFixture Magento/Customer/_files/customer.php - * @magentoApiDataFixture Magento/Sales/_files/orders_with_customer.php - */ + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Sales/_files/orders_with_customer.php + */ public function testOrdersQuery() { - $query = - <<<QUERY + $query = + <<<QUERY query { customerOrders { items { - id - increment_id - created_at - grand_total - status - } + id + increment_id + created_at + grand_total + status + } } } QUERY; - $currentEmail = 'customer@example.com'; - $currentPassword = 'password'; - - $response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword)); + $currentEmail = 'customer@example.com'; + $currentPassword = 'password'; + $response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword)); - $expectedData = [ - [ - 'increment_id' => '100000002', - 'status' => 'processing', - 'grand_total' => 120.00 - ], - [ - 'increment_id' => '100000003', - 'status' => 'processing', - 'grand_total' => 130.00 - ], - [ - 'increment_id' => '100000004', - 'status' => 'closed', - 'grand_total' => 140.00 - ], - [ - 'increment_id' => '100000005', - 'status' => 'complete', - 'grand_total' => 150.00 - ], - [ - 'increment_id' => '100000006', - 'status' => 'complete', - 'grand_total' => 160.00 - ] - ]; + $expectedData = [ + [ + 'increment_id' => '100000002', + 'status' => 'processing', + 'grand_total' => 120.00 + ], + [ + 'increment_id' => '100000003', + 'status' => 'processing', + 'grand_total' => 130.00 + ], + [ + 'increment_id' => '100000004', + 'status' => 'closed', + 'grand_total' => 140.00 + ], + [ + 'increment_id' => '100000005', + 'status' => 'complete', + 'grand_total' => 150.00 + ], + [ + 'increment_id' => '100000006', + 'status' => 'complete', + 'grand_total' => 160.00 + ] + ]; - $actualData = $response['customerOrders']['items']; + $actualData = $response['customerOrders']['items']; - foreach ($expectedData as $key => $data) { - $this->assertEquals($data['increment_id'], $actualData[$key]['increment_id']); - $this->assertEquals($data['grand_total'], $actualData[$key]['grand_total']); - $this->assertEquals($data['status'], $actualData[$key]['status']); - } + foreach ($expectedData as $key => $data) { + $this->assertEquals($data['increment_id'], $actualData[$key]['increment_id']); + $this->assertEquals($data['grand_total'], $actualData[$key]['grand_total']); + $this->assertEquals($data['status'], $actualData[$key]['status']); + } } - /** - * @param string $email - * @param string $password - * @return array - * @throws \Magento\Framework\Exception\AuthenticationException - */ - private function getCustomerAuthHeaders(string $email, string $password): array - { - $customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password); - return ['Authorization' => 'Bearer ' . $customerToken]; - } + /** + * @param string $email + * @param string $password + * @return array + * @throws \Magento\Framework\Exception\AuthenticationException + */ + private function getCustomerAuthHeaders(string $email, string $password): array + { + $customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password); + return ['Authorization' => 'Bearer ' . $customerToken]; + } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php index e649396391ca9..6906166f7cbe5 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php @@ -14,88 +14,88 @@ /** @var Order\Item $orderItem */ /** @var array $addressData Data for creating addresses for the orders. */ $orders = [ - [ - 'increment_id' => '100000002', - 'state' => \Magento\Sales\Model\Order::STATE_NEW, - 'status' => 'processing', - 'grand_total' => 120.00, - 'subtotal' => 120.00, - 'base_grand_total' => 120.00, - 'store_id' => 1, - 'website_id' => 1, - 'payment' => $payment - ], - [ - 'increment_id' => '100000003', - 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, - 'status' => 'processing', - 'grand_total' => 130.00, - 'base_grand_total' => 130.00, - 'subtotal' => 130.00, - 'store_id' => 0, - 'website_id' => 0, - 'payment' => $payment - ], - [ - 'increment_id' => '100000004', - 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, - 'status' => 'closed', - 'grand_total' => 140.00, - 'base_grand_total' => 140.00, - 'subtotal' => 140.00, - 'store_id' => 1, - 'website_id' => 1, - 'payment' => $payment - ], - [ - 'increment_id' => '100000005', - 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, - 'status' => 'complete', - 'grand_total' => 150.00, - 'base_grand_total' => 150.00, - 'subtotal' => 150.00, - 'store_id' => 1, - 'website_id' => 1, - 'payment' => $payment - ], - [ - 'increment_id' => '100000006', - 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, - 'status' => 'complete', - 'grand_total' => 160.00, - 'base_grand_total' => 160.00, - 'subtotal' => 160.00, - 'store_id' => 1, - 'website_id' => 1, - 'payment' => $payment - ], + [ + 'increment_id' => '100000002', + 'state' => \Magento\Sales\Model\Order::STATE_NEW, + 'status' => 'processing', + 'grand_total' => 120.00, + 'subtotal' => 120.00, + 'base_grand_total' => 120.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000003', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'processing', + 'grand_total' => 130.00, + 'base_grand_total' => 130.00, + 'subtotal' => 130.00, + 'store_id' => 0, + 'website_id' => 0, + 'payment' => $payment + ], + [ + 'increment_id' => '100000004', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'closed', + 'grand_total' => 140.00, + 'base_grand_total' => 140.00, + 'subtotal' => 140.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000005', + 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, + 'status' => 'complete', + 'grand_total' => 150.00, + 'base_grand_total' => 150.00, + 'subtotal' => 150.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000006', + 'state' => \Magento\Sales\Model\Order::STATE_COMPLETE, + 'status' => 'complete', + 'grand_total' => 160.00, + 'base_grand_total' => 160.00, + 'subtotal' => 160.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], ]; /** @var OrderRepositoryInterface $orderRepository */ $orderRepository = $objectManager->create(OrderRepositoryInterface::class); /** @var array $orderData */ foreach ($orders as $orderData) { - /** @var $order \Magento\Sales\Model\Order */ - $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Sales\Model\Order::class - ); + /** @var $order \Magento\Sales\Model\Order */ + $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\Order::class + ); - // Reset addresses - /** @var Order\Address $billingAddress */ - $billingAddress = $objectManager->create(OrderAddress::class, ['data' => $addressData]); - $billingAddress->setAddressType('billing'); + // Reset addresses + /** @var Order\Address $billingAddress */ + $billingAddress = $objectManager->create(OrderAddress::class, ['data' => $addressData]); + $billingAddress->setAddressType('billing'); - $shippingAddress = clone $billingAddress; - $shippingAddress->setId(null)->setAddressType('shipping'); + $shippingAddress = clone $billingAddress; + $shippingAddress->setId(null)->setAddressType('shipping'); - $order - ->setData($orderData) - ->addItem($orderItem) - ->setCustomerIsGuest(false) - ->setCustomerId(1) - ->setCustomerEmail('customer@example.com') - ->setBillingAddress($billingAddress) - ->setShippingAddress($shippingAddress); + $order + ->setData($orderData) + ->addItem($orderItem) + ->setCustomerIsGuest(false) + ->setCustomerId(1) + ->setCustomerEmail('customer@example.com') + ->setBillingAddress($billingAddress) + ->setShippingAddress($shippingAddress); - $orderRepository->save($order); + $orderRepository->save($order); } From 198fc61326ad0c575997649e649753d946ac3b70 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 12 Nov 2018 16:08:57 +0200 Subject: [PATCH 742/812] GraphQl-41: [Query] My Account > My Orders --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index d4ac4fc091bbc..7fc23572cbb34 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "78153b5c8150c0d145b3372a534a45eb", + "content-hash": "7986e75e7ec3308bfd361f2076544eb7", "packages": [ { "name": "braintree/braintree_php", From a04317746efcaa2aa00c04930a5de428e2753ac1 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 12 Nov 2018 16:11:11 +0200 Subject: [PATCH 743/812] GraphQl-41: [Query] My Account > My Orders --- app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php index f058ce9ae3bdd..5802115d44b5e 100644 --- a/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php +++ b/app/code/Magento/SalesGraphQl/Model/Resolver/Orders.php @@ -38,7 +38,6 @@ public function __construct( ) { $this->collectionFactory = $collectionFactory; $this->checkCustomerAccount = $checkCustomerAccount; - } /** From 34af04fc6f288e217129ed32a82a60a51bdce5b9 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Mon, 12 Nov 2018 17:11:25 +0300 Subject: [PATCH 744/812] MAGETWO-91784: On Payment screen up and down arrow key allow to add -ve numbers - Fixed static test. --- .../view/base/web/js/model/credit-card-validation/validator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js index f9af514a6d4da..c41be40cba144 100644 --- a/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js +++ b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js @@ -23,7 +23,7 @@ }(function ($, cvvValidator, creditCardNumberValidator, yearValidator, monthValidator, creditCardData) { 'use strict'; - $('.payment-method-content input[type="number"]').on('keyup', function() { + $('.payment-method-content input[type="number"]').on('keyup', function () { if ($(this).val() < 0) { $(this).val($(this).val().replace(/^-/, '')); } From 7e5be32f56ac80bde8dbd6d8e55da12c3923dbb4 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Mon, 12 Nov 2018 17:18:10 +0300 Subject: [PATCH 745/812] MAGETWO-62728: My Wishlist - quantity input box issue - Fixed static test. --- .../Wishlist/view/frontend/templates/item/column/cart.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml index c1cccae85971c..7578774fabc2c 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml @@ -22,7 +22,7 @@ $allowedQty = $block->getMinMaxQty(); <div class="field qty"> <label class="label" for="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]"><span><?= $block->escapeHtml(__('Qty')) ?></span></label> <div class="control"> - <input type="number" data-role="qty" id="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true, 'validate-item-quantity':{'minAllowed':<?= $allowedQty['minAllowed'] ?>,'maxAllowed':<?= $allowedQty['maxAllowed'] ?>}}" + <input type="number" data-role="qty" id="qty[<?= /* @noEscape */ $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true, 'validate-item-quantity':{'minAllowed':<?= $allowedQty['minAllowed'] ?>,'maxAllowed':<?= $allowedQty['maxAllowed'] ?>}}" name="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" value="<?= /* @noEscape */ (int)($block->getAddToCartQty($item) * 1) ?>"> </div> </div> From abc43aca2b420e0b4baebab6c414e2f20a63a3c1 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 12 Nov 2018 16:49:40 +0200 Subject: [PATCH 746/812] GraphQl-41: [Query] My Account > My Orders --- app/code/Magento/SalesGraphQl/composer.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/code/Magento/SalesGraphQl/composer.json b/app/code/Magento/SalesGraphQl/composer.json index 3e29adbe7009e..0549d31d59a24 100644 --- a/app/code/Magento/SalesGraphQl/composer.json +++ b/app/code/Magento/SalesGraphQl/composer.json @@ -5,12 +5,8 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-customer": "*", "magento/module-customer-graph-ql": "*", - "magento/module-catalog": "*", - "magento/module-sales": "*", - "magento/module-store": "*" + "magento/module-sales": "*" }, "suggest": { "magento/module-graph-ql": "*" From 0aad3fb3eeea271eed53f923d0464147666135a5 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 12 Nov 2018 17:02:06 +0200 Subject: [PATCH 747/812] GraphQl-41: [Query] My Account > My Orders --- .../testsuite/Magento/Sales/_files/orders_with_customer.php | 1 + .../Magento/Sales/_files/orders_with_customer_rollback.php | 1 + 2 files changed, 2 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php index 6906166f7cbe5..753adb1f38596 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); use Magento\Sales\Model\Order; use Magento\Sales\Api\OrderRepositoryInterface; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php index 6e24cee501f51..1fb4b4636ab29 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/orders_with_customer_rollback.php @@ -3,5 +3,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); require 'default_rollback.php'; From 0566957554fa964f79518b7b93920fe12db39c8a Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 12 Nov 2018 17:03:30 +0200 Subject: [PATCH 748/812] magento/magento2#18939: [Forwardport] fixed js translation. --- app/code/Magento/Tax/i18n/en_US.csv | 1 + .../Tax/view/frontend/web/js/view/checkout/summary/tax.js | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Tax/i18n/en_US.csv b/app/code/Magento/Tax/i18n/en_US.csv index e6d89deb7696c..836221e2ec974 100644 --- a/app/code/Magento/Tax/i18n/en_US.csv +++ b/app/code/Magento/Tax/i18n/en_US.csv @@ -178,3 +178,4 @@ Rate,Rate "Your credit card will be charged for","Your credit card will be charged for" "An error occurred while loading tax rates.","An error occurred while loading tax rates." "You will be charged for","You will be charged for" +"Not yet calculated", "Not yet calculated" diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js index c86c3b4d1ab06..b21be98531ba9 100644 --- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js +++ b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js @@ -11,8 +11,9 @@ define([ 'ko', 'Magento_Checkout/js/view/summary/abstract-total', 'Magento_Checkout/js/model/quote', - 'Magento_Checkout/js/model/totals' -], function (ko, Component, quote, totals) { + 'Magento_Checkout/js/model/totals', + 'mage/translate' +], function (ko, Component, quote, totals, $t) { 'use strict'; var isTaxDisplayedInGrandTotal = window.checkoutConfig.includeTaxInGrandTotal, @@ -22,7 +23,7 @@ define([ return Component.extend({ defaults: { isTaxDisplayedInGrandTotal: isTaxDisplayedInGrandTotal, - notCalculatedMessage: 'Not yet calculated', + notCalculatedMessage: $t('Not yet calculated'), template: 'Magento_Tax/checkout/summary/tax' }, totals: quote.getTotals(), From 84a3cd8f9c7aa58fccf8f71e527e26295529268a Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Mon, 12 Nov 2018 18:55:56 +0200 Subject: [PATCH 749/812] Covering the CheckUserLoginBackendObserver by Unit Test --- .../CheckUserLoginBackendObserverTest.php | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php diff --git a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php new file mode 100644 index 0000000000000..b7b11a56fd5ce --- /dev/null +++ b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php @@ -0,0 +1,174 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Captcha\Test\Unit\Observer; + +use Magento\Captcha\Helper\Data; +use Magento\Captcha\Model\DefaultModel; +use Magento\Captcha\Observer\CaptchaStringResolver; +use Magento\Captcha\Observer\CheckUserLoginBackendObserver; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Event; +use Magento\Framework\Event\Observer; +use Magento\Framework\Exception\Plugin\AuthenticationException; +use Magento\Framework\Message\ManagerInterface; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +/** + * Class CheckUserLoginBackendObserverTest + */ +class CheckUserLoginBackendObserverTest extends TestCase +{ + /** + * @var CheckUserLoginBackendObserver + */ + private $observer; + + /** + * @var ManagerInterface|MockObject + */ + private $messageManagerMock; + + /** + * @var CaptchaStringResolver|MockObject + */ + private $captchaStringResolverMock; + + /** + * @var RequestInterface|MockObject + */ + private $requestMock; + + /** + * @var Data|MockObject + */ + private $helperMock; + + /** + * Set Up + * + * @return void + */ + protected function setUp() + { + $this->helperMock = $this->createMock(Data::class); + $this->messageManagerMock = $this->createMock(ManagerInterface::class); + $this->captchaStringResolverMock = $this->createMock(CaptchaStringResolver::class); + $this->requestMock = $this->createMock(RequestInterface::class); + + $this->observer = new CheckUserLoginBackendObserver( + $this->helperMock, + $this->captchaStringResolverMock, + $this->requestMock + ); + } + + /** + * Test check user login in backend with correct captcha + * + * @dataProvider captchaCorrectnessCheckDataProvider + * @param bool $isRequired + * @param bool $isCorrect + * @param int $invokedTimes + * @return void + * @throws AuthenticationException + */ + public function testCheckOnBackendLoginWithCorrectCaptcha($isRequired, $isCorrect, $invokedTimes) + { + $formId = 'backend_login'; + $login = 'admin'; + $captchaValue = 'captcha-value'; + + $observerMock = $this->createPartialMock(Observer::class, ['getEvent']); + $eventMock = $this->createPartialMock(Event::class, ['getUsername']); + $captcha = $this->createMock(DefaultModel::class); + + $eventMock->expects($this->any()) + ->method('getUsername') + ->willReturn('admin'); + $observerMock->expects($this->any()) + ->method('getEvent') + ->willReturn($eventMock); + $captcha->expects($this->once())->method('isRequired') + ->with($login) + ->willReturn($isRequired); + $captcha->expects($this->exactly($invokedTimes)) + ->method('isCorrect') + ->with($captchaValue) + ->willReturn($isCorrect); + $this->helperMock->expects($this->once()) + ->method('getCaptcha') + ->with($formId) + ->willReturn($captcha); + + $this->captchaStringResolverMock->expects($this->exactly($invokedTimes)) + ->method('resolve') + ->with($this->requestMock, $formId) + ->willReturn($captchaValue); + + $this->messageManagerMock->expects($this->exactly(0)) + ->method('addError') + ->with(__('Incorrect CAPTCHA')); + + $this->observer->execute($observerMock); + } + + /** + * @return array + */ + public function captchaCorrectnessCheckDataProvider() + { + return [ + [true, true, 1], + [false, true, 0] + ]; + } + + + /** + * Test check user login in backend with wrong captcha + * + * @return void + * @throws AuthenticationException + */ + public function testCheckOnBackendLoginWithWrongCaptcha() + { + $formId = 'backend_login'; + $login = 'admin'; + $captchaValue = 'captcha-value'; + + $observerMock = $this->createPartialMock(Observer::class, ['getEvent']); + $eventMock = $this->createPartialMock(Event::class, ['getUsername']); + $captcha = $this->createMock(DefaultModel::class); + + $eventMock->expects($this->any()) + ->method('getUsername') + ->willReturn('admin'); + $observerMock->expects($this->any()) + ->method('getEvent') + ->willReturn($eventMock); + $captcha->expects($this->once())->method('isRequired') + ->with($login) + ->willReturn(true); + $captcha->expects($this->exactly(1)) + ->method('isCorrect') + ->with($captchaValue) + ->willReturn(false); + $this->helperMock->expects($this->once()) + ->method('getCaptcha') + ->with($formId) + ->willReturn($captcha); + + $this->captchaStringResolverMock->expects($this->exactly(1)) + ->method('resolve') + ->with($this->requestMock, $formId) + ->willReturn($captchaValue); + + $this->expectException(AuthenticationException::class, 'Incorrect CAPTCHA.'); + + $this->observer->execute($observerMock); + } +} From 246eb673397e7358bc1ee295bec59ef66b6cfba2 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Mon, 12 Nov 2018 19:02:12 +0200 Subject: [PATCH 750/812] Adding strict types --- .../Observer/CheckUserLoginBackendObserverTest.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php index b7b11a56fd5ce..02f6bed520acd 100644 --- a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php +++ b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Captcha\Test\Unit\Observer; use Magento\Captcha\Helper\Data; @@ -76,12 +78,13 @@ protected function setUp() * @return void * @throws AuthenticationException */ - public function testCheckOnBackendLoginWithCorrectCaptcha($isRequired, $isCorrect, $invokedTimes) + public function testCheckOnBackendLoginWithCorrectCaptcha(bool $isRequired, bool $isCorrect, int $invokedTimes): void { $formId = 'backend_login'; $login = 'admin'; $captchaValue = 'captcha-value'; + /** @var Observer|MockObject $observerMock */ $observerMock = $this->createPartialMock(Observer::class, ['getEvent']); $eventMock = $this->createPartialMock(Event::class, ['getUsername']); $captcha = $this->createMock(DefaultModel::class); @@ -119,7 +122,7 @@ public function testCheckOnBackendLoginWithCorrectCaptcha($isRequired, $isCorrec /** * @return array */ - public function captchaCorrectnessCheckDataProvider() + public function captchaCorrectnessCheckDataProvider(): array { return [ [true, true, 1], @@ -134,12 +137,13 @@ public function captchaCorrectnessCheckDataProvider() * @return void * @throws AuthenticationException */ - public function testCheckOnBackendLoginWithWrongCaptcha() + public function testCheckOnBackendLoginWithWrongCaptcha(): void { $formId = 'backend_login'; $login = 'admin'; $captchaValue = 'captcha-value'; + /** @var Observer|MockObject $observerMock */ $observerMock = $this->createPartialMock(Observer::class, ['getEvent']); $eventMock = $this->createPartialMock(Event::class, ['getUsername']); $captcha = $this->createMock(DefaultModel::class); @@ -167,7 +171,7 @@ public function testCheckOnBackendLoginWithWrongCaptcha() ->with($this->requestMock, $formId) ->willReturn($captchaValue); - $this->expectException(AuthenticationException::class, 'Incorrect CAPTCHA.'); + $this->expectException(AuthenticationException::class); $this->observer->execute($observerMock); } From 548ca3c97565e99ebe8bcfa42e1f421de23c4898 Mon Sep 17 00:00:00 2001 From: Alexandr Voronoy <servermed@gmail.com> Date: Mon, 12 Nov 2018 19:11:54 +0200 Subject: [PATCH 751/812] Added option_id in response for product with customizable options. --- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 1 + .../testsuite/Magento/GraphQl/Catalog/ProductViewTest.php | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 5efe37d8f91f6..5c15d1f4a07e7 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -358,6 +358,7 @@ interface CustomizableOptionInterface @typeResolver(class: "Magento\\CatalogGrap title: String @doc(description: "The display name for this option") required: Boolean @doc(description: "Indicates whether the option is required") sort_order: Int @doc(description: "The order in which the option is displayed") + option_id: Int @doc(description: "Option ID") } interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description: "CustomizableProductInterface contains information about customizable product options.") { 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 791696b2fa29e..77384165db97f 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -91,6 +91,7 @@ public function testQueryAllFieldsSimpleProduct() title required sort_order + option_id ... on CustomizableFieldOption { product_sku field_option: value { @@ -337,6 +338,7 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct() title required sort_order + option_id ... on CustomizableFieldOption { product_sku field_option: value { @@ -753,7 +755,8 @@ private function assertOptions($product, $actualResponse) $assertionMap = [ ['response_field' => 'sort_order', 'expected_value' => $option->getSortOrder()], ['response_field' => 'title', 'expected_value' => $option->getTitle()], - ['response_field' => 'required', 'expected_value' => $option->getIsRequire()] + ['response_field' => 'required', 'expected_value' => $option->getIsRequire()], + ['response_field' => 'option_id', 'expected_value' => $option->getOptionId()] ]; if (!empty($option->getValues())) { @@ -777,7 +780,7 @@ private function assertOptions($product, $actualResponse) ['response_field' => 'product_sku', 'expected_value' => $option->getProductSku()], ] ); - $valueKeyName = ""; + if ($option->getType() === 'file') { $valueKeyName = 'file_option'; $valueAssertionMap = [ From 815f013d2a04212f69ae84871eb2d22ea60efcad Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Mon, 12 Nov 2018 16:17:38 -0600 Subject: [PATCH 752/812] #2331: Fixing static tests --- app/code/Magento/Customer/Controller/Section/Load.php | 2 +- app/code/Magento/Customer/CustomerData/Section/Identifier.php | 2 +- app/code/Magento/Customer/CustomerData/SectionPool.php | 2 +- .../Magento/Customer/Controller/Section/LoadTest.php | 4 +++- lib/internal/Magento/Framework/Test/Unit/TranslateTest.php | 1 + 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Section/Load.php b/app/code/Magento/Customer/Controller/Section/Load.php index 89d4417c79c19..37cd071b13623 100644 --- a/app/code/Magento/Customer/Controller/Section/Load.php +++ b/app/code/Magento/Customer/Controller/Section/Load.php @@ -59,7 +59,7 @@ public function __construct( } /** - * @return \Magento\Framework\Controller\Result\Json + * @inheritdoc */ public function execute() { diff --git a/app/code/Magento/Customer/CustomerData/Section/Identifier.php b/app/code/Magento/Customer/CustomerData/Section/Identifier.php index 54d7cee2d90bd..a8bc2c8abc11a 100644 --- a/app/code/Magento/Customer/CustomerData/Section/Identifier.php +++ b/app/code/Magento/Customer/CustomerData/Section/Identifier.php @@ -67,7 +67,7 @@ public function initMark($forceNewTimestamp) * Mark sections with data id * * @param array $sectionsData - * @param null $sectionNames + * @param array|null $sectionNames * @param bool $forceNewTimestamp * @return array */ diff --git a/app/code/Magento/Customer/CustomerData/SectionPool.php b/app/code/Magento/Customer/CustomerData/SectionPool.php index 618d52079973d..efea1762d9de6 100644 --- a/app/code/Magento/Customer/CustomerData/SectionPool.php +++ b/app/code/Magento/Customer/CustomerData/SectionPool.php @@ -53,7 +53,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getSectionsData(array $sectionNames = null, $forceNewTimestamp = false) { diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php index 3563087d3722b..3db22b8379850 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php @@ -13,7 +13,9 @@ public function testLoadInvalidSection() $expected = [ 'message' => 'The "section<invalid" section source isn't supported.', ]; - $this->dispatch('/customer/section/load/?sections=section<invalid&force_new_section_timestamp=false&_=147066166394'); + $this->dispatch( + '/customer/section/load/?sections=section<invalid&force_new_section_timestamp=false&_=147066166394' + ); self::assertEquals(json_encode($expected), $this->getResponse()->getBody()); } } diff --git a/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php b/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php index 885be8557fa10..0ec27d6d053c3 100644 --- a/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/TranslateTest.php @@ -11,6 +11,7 @@ use Magento\Framework\Translate; /** + * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class TranslateTest extends \PHPUnit\Framework\TestCase From 993ba971580958cdcdb779c80c193bd86183776c Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Tue, 13 Nov 2018 09:47:20 +0200 Subject: [PATCH 753/812] Adjusting the Unit Test strictness --- .../CheckUserLoginBackendObserverTest.php | 76 +++++-------------- 1 file changed, 18 insertions(+), 58 deletions(-) diff --git a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php index 02f6bed520acd..2d0a2a7e1c99a 100644 --- a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php +++ b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php @@ -14,7 +14,6 @@ use Magento\Framework\App\RequestInterface; use Magento\Framework\Event; use Magento\Framework\Event\Observer; -use Magento\Framework\Exception\Plugin\AuthenticationException; use Magento\Framework\Message\ManagerInterface; use PHPUnit\Framework\TestCase; use PHPUnit_Framework_MockObject_MockObject as MockObject; @@ -71,14 +70,11 @@ protected function setUp() /** * Test check user login in backend with correct captcha * - * @dataProvider captchaCorrectnessCheckDataProvider + * @dataProvider requiredCaptchaDataProvider * @param bool $isRequired - * @param bool $isCorrect - * @param int $invokedTimes * @return void - * @throws AuthenticationException */ - public function testCheckOnBackendLoginWithCorrectCaptcha(bool $isRequired, bool $isCorrect, int $invokedTimes): void + public function testCheckOnBackendLoginWithCorrectCaptcha(bool $isRequired): void { $formId = 'backend_login'; $login = 'admin'; @@ -89,44 +85,25 @@ public function testCheckOnBackendLoginWithCorrectCaptcha(bool $isRequired, bool $eventMock = $this->createPartialMock(Event::class, ['getUsername']); $captcha = $this->createMock(DefaultModel::class); - $eventMock->expects($this->any()) - ->method('getUsername') - ->willReturn('admin'); - $observerMock->expects($this->any()) - ->method('getEvent') - ->willReturn($eventMock); - $captcha->expects($this->once())->method('isRequired') - ->with($login) - ->willReturn($isRequired); - $captcha->expects($this->exactly($invokedTimes)) - ->method('isCorrect') - ->with($captchaValue) - ->willReturn($isCorrect); - $this->helperMock->expects($this->once()) - ->method('getCaptcha') - ->with($formId) - ->willReturn($captcha); - - $this->captchaStringResolverMock->expects($this->exactly($invokedTimes)) - ->method('resolve') - ->with($this->requestMock, $formId) + $eventMock->method('getUsername')->willReturn('admin'); + $observerMock->method('getEvent')->willReturn($eventMock); + $captcha->method('isRequired')->with($login)->willReturn($isRequired); + $captcha->method('isCorrect')->with($captchaValue)->willReturn(true); + $this->helperMock->method('getCaptcha')->with($formId)->willReturn($captcha); + $this->captchaStringResolverMock->method('resolve')->with($this->requestMock, $formId) ->willReturn($captchaValue); - $this->messageManagerMock->expects($this->exactly(0)) - ->method('addError') - ->with(__('Incorrect CAPTCHA')); - $this->observer->execute($observerMock); } /** * @return array */ - public function captchaCorrectnessCheckDataProvider(): array + public function requiredCaptchaDataProvider(): array { return [ - [true, true, 1], - [false, true, 0] + [true], + [false] ]; } @@ -135,7 +112,7 @@ public function captchaCorrectnessCheckDataProvider(): array * Test check user login in backend with wrong captcha * * @return void - * @throws AuthenticationException + * @expectedException \Magento\Framework\Exception\Plugin\AuthenticationException */ public function testCheckOnBackendLoginWithWrongCaptcha(): void { @@ -148,31 +125,14 @@ public function testCheckOnBackendLoginWithWrongCaptcha(): void $eventMock = $this->createPartialMock(Event::class, ['getUsername']); $captcha = $this->createMock(DefaultModel::class); - $eventMock->expects($this->any()) - ->method('getUsername') - ->willReturn('admin'); - $observerMock->expects($this->any()) - ->method('getEvent') - ->willReturn($eventMock); - $captcha->expects($this->once())->method('isRequired') - ->with($login) - ->willReturn(true); - $captcha->expects($this->exactly(1)) - ->method('isCorrect') - ->with($captchaValue) - ->willReturn(false); - $this->helperMock->expects($this->once()) - ->method('getCaptcha') - ->with($formId) - ->willReturn($captcha); - - $this->captchaStringResolverMock->expects($this->exactly(1)) - ->method('resolve') - ->with($this->requestMock, $formId) + $eventMock->method('getUsername')->willReturn($login); + $observerMock->method('getEvent')->willReturn($eventMock); + $captcha->method('isRequired')->with($login)->willReturn(true); + $captcha->method('isCorrect')->with($captchaValue)->willReturn(false); + $this->helperMock->method('getCaptcha')->with($formId)->willReturn($captcha); + $this->captchaStringResolverMock->method('resolve')->with($this->requestMock, $formId) ->willReturn($captchaValue); - $this->expectException(AuthenticationException::class); - $this->observer->execute($observerMock); } } From 8f463db4808afc9f8f4908a4dee65f3abe981eba Mon Sep 17 00:00:00 2001 From: vgelani <vishalgelani99@gmail.com> Date: Mon, 22 Oct 2018 18:23:19 +0530 Subject: [PATCH 754/812] Added tier price logic for special price --- .../Model/Product/Attribute/Backend/Tierprice.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php index 92b9a2e4239b2..55b5c6c925b05 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -159,8 +159,22 @@ protected function validatePrice(array $priceRow) */ protected function modifyPriceData($object, $data) { + /** @var \Magento\Catalog\Model\Product $object */ $data = parent::modifyPriceData($object, $data); $price = $object->getPrice(); + + $specialPrice = $object->getSpecialPrice(); + $specialPriceFromDate = $object->getSpecialFromDate(); + $specialPriceToDate = $object->getSpecialToDate(); + $today = time(); + + if ($specialPrice && ($object->getPrice() > $object->getFinalPrice())){ + if ($today >= strtotime($specialPriceFromDate) && $today <= strtotime($specialPriceToDate) || + $today >= strtotime($specialPriceFromDate) && is_null($specialPriceToDate)) { + $price = $specialPrice; + } + } + foreach ($data as $key => $tierPrice) { $percentageValue = $this->getPercentage($tierPrice); if ($percentageValue) { From 63c9ea46673e58f2712da5a768d0840ece184152 Mon Sep 17 00:00:00 2001 From: Vishal Gelani <vishalgelani99@gmail.com> Date: Tue, 23 Oct 2018 08:19:55 +0530 Subject: [PATCH 755/812] Fixed code standard error --- .../Catalog/Model/Product/Attribute/Backend/Tierprice.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php index 55b5c6c925b05..88d8198d0249e 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -168,9 +168,9 @@ protected function modifyPriceData($object, $data) $specialPriceToDate = $object->getSpecialToDate(); $today = time(); - if ($specialPrice && ($object->getPrice() > $object->getFinalPrice())){ + if ($specialPrice && ($object->getPrice() > $object->getFinalPrice())) { if ($today >= strtotime($specialPriceFromDate) && $today <= strtotime($specialPriceToDate) || - $today >= strtotime($specialPriceFromDate) && is_null($specialPriceToDate)) { + $today >= strtotime($specialPriceFromDate) && is_null($specialPriceToDate) === TRUE) { $price = $specialPrice; } } From 77492c1c08695753b3a274b02552fab7be9c64c0 Mon Sep 17 00:00:00 2001 From: Vishal Gelani <vishalgelani99@gmail.com> Date: Tue, 23 Oct 2018 16:27:07 +0530 Subject: [PATCH 756/812] Update Tierprice.php --- .../Catalog/Model/Product/Attribute/Backend/Tierprice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php index 88d8198d0249e..b74be1372a3c0 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -170,7 +170,7 @@ protected function modifyPriceData($object, $data) if ($specialPrice && ($object->getPrice() > $object->getFinalPrice())) { if ($today >= strtotime($specialPriceFromDate) && $today <= strtotime($specialPriceToDate) || - $today >= strtotime($specialPriceFromDate) && is_null($specialPriceToDate) === TRUE) { + $today >= strtotime($specialPriceFromDate) && is_null($specialPriceToDate)) { $price = $specialPrice; } } From d0ba9973dffac27560364906b22786d70410d69d Mon Sep 17 00:00:00 2001 From: Vishal Gelani <vishalgelani99@gmail.com> Date: Thu, 1 Nov 2018 17:59:10 +0530 Subject: [PATCH 757/812] Update Tierprice.php --- .../Catalog/Model/Product/Attribute/Backend/Tierprice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php index b74be1372a3c0..23b2dfa01bfbd 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -170,7 +170,7 @@ protected function modifyPriceData($object, $data) if ($specialPrice && ($object->getPrice() > $object->getFinalPrice())) { if ($today >= strtotime($specialPriceFromDate) && $today <= strtotime($specialPriceToDate) || - $today >= strtotime($specialPriceFromDate) && is_null($specialPriceToDate)) { + $today >= strtotime($specialPriceFromDate) && $specialPriceToDate === null) { $price = $specialPrice; } } From b1bf89323d5bd6a84f45dd3c7788b2c60312b345 Mon Sep 17 00:00:00 2001 From: "Lopukhov, Stanislav" <lopukhov@adobe.com> Date: Tue, 13 Nov 2018 10:23:41 +0200 Subject: [PATCH 758/812] MAGETWO-96118: Few optimizations on category & product pages --- .../Model/Product/Gallery/ReadHandler.php | 41 +++------------- .../Model/ResourceModel/Product/Gallery.php | 13 +++-- .../ResourceModel/Product/GalleryTest.php | 48 +++++++++++++++---- app/code/Magento/Catalog/etc/db_schema.xml | 5 ++ .../Catalog/etc/db_schema_whitelist.json | 5 +- .../Model/Product/Type/Configurable.php | 44 +++++++++++++---- .../Product/Type/Configurable.php | 11 +++-- .../Pricing/Renderer/SalableResolver.php | 4 +- .../Plugin/ExternalVideoResourceBackend.php | 40 ++++++++-------- 9 files changed, 127 insertions(+), 84 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php b/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php index c785d08e64b7f..4ad275bc70f90 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php @@ -55,9 +55,6 @@ public function __construct( */ public function execute($entity, $arguments = []) { - $value = []; - $value['images'] = []; - $mediaEntries = $this->resourceModel->loadProductGalleryByAttributeId( $entity, $this->getAttribute()->getAttributeId() @@ -79,37 +76,13 @@ public function execute($entity, $arguments = []) */ public function addMediaDataToProduct(Product $product, array $mediaEntries) { - $attrCode = $this->getAttribute()->getAttributeCode(); - $value = []; - $value['images'] = []; - $value['values'] = []; - - foreach ($mediaEntries as $mediaEntry) { - $mediaEntry = $this->substituteNullsWithDefaultValues($mediaEntry); - $value['images'][$mediaEntry['value_id']] = $mediaEntry; - } - $product->setData($attrCode, $value); - } - - /** - * @param array $rawData - * @return array - */ - private function substituteNullsWithDefaultValues(array $rawData) - { - $processedData = []; - foreach ($rawData as $key => $rawValue) { - if (null !== $rawValue) { - $processedValue = $rawValue; - } elseif (isset($rawData[$key . '_default'])) { - $processedValue = $rawData[$key . '_default']; - } else { - $processedValue = null; - } - $processedData[$key] = $processedValue; - } - - return $processedData; + $product->setData( + $this->getAttribute()->getAttributeCode(), + [ + 'images' => array_column($mediaEntries, null, 'value_id'), + 'values' => [] + ] + ); } /** diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php index 2868392f85280..b68c43e40ff2f 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php @@ -190,7 +190,7 @@ public function createBatchBaseSelect($storeId, $attributeId) 'value.' . $linkField . ' = entity.' . $linkField, ] ), - ['label', 'position', 'disabled'] + [] )->joinLeft( ['default_value' => $this->getTable(self::GALLERY_VALUE_TABLE)], implode( @@ -201,8 +201,15 @@ public function createBatchBaseSelect($storeId, $attributeId) 'default_value.' . $linkField . ' = entity.' . $linkField, ] ), - ['label_default' => 'label', 'position_default' => 'position', 'disabled_default' => 'disabled'] - )->where( + [] + )->columns([ + 'label' => $this->getConnection()->getIfNullSql('`value`.`label`', '`default_value`.`label`'), + 'position' => $this->getConnection()->getIfNullSql('`value`.`position`', '`default_value`.`position`'), + 'disabled' => $this->getConnection()->getIfNullSql('`value`.`disabled`', '`default_value`.`disabled`'), + 'label_default' => 'default_value.label', + 'position_default' => 'default_value.position', + 'disabled_default' => 'default_value.disabled' + ])->where( $mainTableAlias . '.attribute_id = ?', $attributeId )->where( diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/GalleryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/GalleryTest.php index dfed4e4f37385..47ef3c999125f 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/GalleryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/GalleryTest.php @@ -281,6 +281,9 @@ public function testBindValueToEntityRecordExists() $this->resource->bindValueToEntity($valueId, $entityId); } + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ public function testLoadGallery() { $productId = 5; @@ -329,7 +332,8 @@ public function testLoadGallery() 'main.value_id = entity.value_id', ['entity_id'] )->willReturnSelf(); - $this->product->expects($this->at(0))->method('getData')->with('entity_id')->willReturn($productId); + $this->product->expects($this->at(0))->method('getData') + ->with('entity_id')->willReturn($productId); $this->product->expects($this->at(1))->method('getStoreId')->will($this->returnValue($storeId)); $this->connection->expects($this->exactly(2))->method('quoteInto')->withConsecutive( ['value.store_id = ?'], @@ -338,26 +342,50 @@ public function testLoadGallery() 'value.store_id = ' . $storeId, 'default_value.store_id = ' . 0 ); + $this->connection->expects($this->any())->method('getIfNullSql')->will( + $this->returnValueMap([ + [ + '`value`.`label`', + '`default_value`.`label`', + 'IFNULL(`value`.`label`, `default_value`.`label`)' + ], + [ + '`value`.`position`', + '`default_value`.`position`', + 'IFNULL(`value`.`position`, `default_value`.`position`)' + ], + [ + '`value`.`disabled`', + '`default_value`.`disabled`', + 'IFNULL(`value`.`disabled`, `default_value`.`disabled`)' + ] + ]) + ); $this->select->expects($this->at(2))->method('joinLeft')->with( ['value' => $getTableReturnValue], $quoteInfoReturnValue, - [ - 'label', - 'position', - 'disabled' - ] + [] )->willReturnSelf(); $this->select->expects($this->at(3))->method('joinLeft')->with( ['default_value' => $getTableReturnValue], $quoteDefaultInfoReturnValue, - ['label_default' => 'label', 'position_default' => 'position', 'disabled_default' => 'disabled'] + [] )->willReturnSelf(); - $this->select->expects($this->at(4))->method('where')->with( + $this->select->expects($this->at(4))->method('columns')->with([ + 'label' => 'IFNULL(`value`.`label`, `default_value`.`label`)', + 'position' => 'IFNULL(`value`.`position`, `default_value`.`position`)', + 'disabled' => 'IFNULL(`value`.`disabled`, `default_value`.`disabled`)', + 'label_default' => 'default_value.label', + 'position_default' => 'default_value.position', + 'disabled_default' => 'default_value.disabled' + ])->willReturnSelf(); + $this->select->expects($this->at(5))->method('where')->with( 'main.attribute_id = ?', $attributeId )->willReturnSelf(); - $this->select->expects($this->at(5))->method('where')->with('main.disabled = 0')->willReturnSelf(); - $this->select->expects($this->at(7))->method('where') + $this->select->expects($this->at(6))->method('where') + ->with('main.disabled = 0')->willReturnSelf(); + $this->select->expects($this->at(8))->method('where') ->with('entity.entity_id = ?', $productId) ->willReturnSelf(); $this->select->expects($this->once())->method('order') diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index a366065c89e76..8dcc623dd64dd 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -835,6 +835,11 @@ <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID" indexType="btree"> <column name="value_id"/> </index> + <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID_VALUE_ID_STORE_ID" indexType="btree"> + <column name="entity_id"/> + <column name="value_id"/> + <column name="store_id"/> + </index> </table> <table name="catalog_product_option" resource="default" engine="innodb" comment="Catalog Product Option Table"> <column xsi:type="int" name="option_id" padding="10" unsigned="true" nullable="false" identity="true" diff --git a/app/code/Magento/Catalog/etc/db_schema_whitelist.json b/app/code/Magento/Catalog/etc/db_schema_whitelist.json index b1543a6a007f9..31620e4e920f4 100644 --- a/app/code/Magento/Catalog/etc/db_schema_whitelist.json +++ b/app/code/Magento/Catalog/etc/db_schema_whitelist.json @@ -484,7 +484,8 @@ "index": { "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_STORE_ID": true, "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID": true, - "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID": true + "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID": true, + "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID_VALUE_ID_STORE_ID": true }, "constraint": { "PRIMARY": true, @@ -1121,4 +1122,4 @@ "CATALOG_PRODUCT_FRONTEND_ACTION_CUSTOMER_ID_PRODUCT_ID_TYPE_ID": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php index 19de63b7a976c..f98075f2294cc 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php @@ -453,6 +453,10 @@ public function getConfigurableAttributes($product) ['group' => 'CONFIGURABLE', 'method' => __METHOD__] ); if (!$product->hasData($this->_configurableAttributes)) { + // for new product do not load configurable attributes + if (!$product->getId()) { + return []; + } $configurableAttributes = $this->getConfigurableAttributeCollection($product); $this->extensionAttributesJoinProcessor->process($configurableAttributes); $configurableAttributes->orderByPosition()->load(); @@ -1398,23 +1402,47 @@ private function getConfiguredUsedProductCollection( $skipStockFilter = true ) { $collection = $this->getUsedProductCollection($product); + if ($skipStockFilter) { $collection->setFlag('has_stock_status_filter', true); } + $collection - ->addAttributeToSelect($this->getCatalogConfig()->getProductAttributes()) + ->addAttributeToSelect($this->getAttributesForCollection($product)) ->addFilterByRequiredOptions() ->setStoreId($product->getStoreId()); - $requiredAttributes = ['name', 'price', 'weight', 'image', 'thumbnail', 'status', 'media_gallery']; - foreach ($requiredAttributes as $attributeCode) { - $collection->addAttributeToSelect($attributeCode); - } - foreach ($this->getUsedProductAttributes($product) as $usedProductAttribute) { - $collection->addAttributeToSelect($usedProductAttribute->getAttributeCode()); - } $collection->addMediaGalleryData(); $collection->addTierPriceData(); + return $collection; } + + /** + * @return array + */ + private function getAttributesForCollection(\Magento\Catalog\Model\Product $product) + { + $productAttributes = $this->getCatalogConfig()->getProductAttributes(); + + $requiredAttributes = [ + 'name', + 'price', + 'weight', + 'image', + 'thumbnail', + 'status', + 'visibility', + 'media_gallery' + ]; + + $usedAttributes = array_map( + function($attr) { + return $attr->getAttributeCode(); + }, + $this->getUsedProductAttributes($product) + ); + + return array_unique(array_merge($productAttributes, $requiredAttributes, $usedAttributes)); + } } diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php index ccff85dd9717f..3611d95f0c6ac 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php @@ -173,10 +173,13 @@ public function getChildrenIds($parentId, $required = true) $parentId ); - $childrenIds = [0 => []]; - foreach ($this->getConnection()->fetchAll($select) as $row) { - $childrenIds[0][$row['product_id']] = $row['product_id']; - } + $childrenIds = [ + 0 => array_column( + $this->getConnection()->fetchAll($select), + 'product_id', + 'product_id' + ) + ]; return $childrenIds; } diff --git a/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php b/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php index efddb278df36c..8a7e846c0e9f1 100644 --- a/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php +++ b/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php @@ -44,9 +44,7 @@ public function afterIsSalable( \Magento\Framework\Pricing\SaleableInterface $salableItem ) { if ($salableItem->getTypeId() == 'configurable' && $result) { - if (!$this->lowestPriceOptionsProvider->getProducts($salableItem)) { - $result = false; - } + $result = $salableItem->isSalable(); } return $result; diff --git a/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php b/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php index dc64f03a42d19..b27c7c8976b4c 100644 --- a/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php +++ b/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php @@ -60,19 +60,9 @@ public function afterCreateBatchBaseSelect(Gallery $originalResourceModel, Selec 'value.store_id = value_video.store_id', ] ), - [ - 'video_provider' => 'provider', - 'video_url' => 'url', - 'video_title' => 'title', - 'video_description' => 'description', - 'video_metadata' => 'metadata' - ] + [] )->joinLeft( - [ - 'default_value_video' => $originalResourceModel->getTable( - 'catalog_product_entity_media_gallery_value_video' - ) - ], + ['default_value_video' => $originalResourceModel->getTable('catalog_product_entity_media_gallery_value_video')], implode( ' AND ', [ @@ -80,14 +70,24 @@ public function afterCreateBatchBaseSelect(Gallery $originalResourceModel, Selec 'default_value.store_id = default_value_video.store_id', ] ), - [ - 'video_provider_default' => 'provider', - 'video_url_default' => 'url', - 'video_title_default' => 'title', - 'video_description_default' => 'description', - 'video_metadata_default' => 'metadata', - ] - ); + [] + )->columns([ + 'video_provider' => $originalResourceModel->getConnection() + ->getIfNullSql('`value_video`.`provider`', '`default_value_video`.`provider`'), + 'video_url' => $originalResourceModel->getConnection() + ->getIfNullSql('`value_video`.`url`', '`default_value_video`.`url`'), + 'video_title' => $originalResourceModel->getConnection() + ->getIfNullSql('`value_video`.`title`', '`default_value_video`.`title`'), + 'video_description' => $originalResourceModel->getConnection() + ->getIfNullSql('`value_video`.`description`', '`default_value_video`.`description`'), + 'video_metadata' => $originalResourceModel->getConnection() + ->getIfNullSql('`value_video`.`metadata`', '`default_value_video`.`metadata`'), + 'video_provider_default' => 'default_value_video.provider', + 'video_url_default' => 'default_value_video.url', + 'video_title_default' => 'default_value_video.title', + 'video_description_default' => 'default_value_video.description', + 'video_metadata_default' => 'default_value_video.metadata', + ]); return $select; } From b1c944b69b3a7504fa3cda663694481debac362a Mon Sep 17 00:00:00 2001 From: "Lopukhov, Stanislav" <lopukhov@adobe.com> Date: Tue, 13 Nov 2018 10:44:18 +0200 Subject: [PATCH 759/812] MAGETWO-96118: Few optimizations on category & product pages --- .../Model/Product/Gallery/ReadHandler.php | 8 ++++++++ .../Model/ResourceModel/Product/Gallery.php | 20 +++++++++++++++++-- .../Product/Type/Configurable.php | 3 +++ .../Pricing/Renderer/SalableResolver.php | 3 +-- .../Plugin/ExternalVideoResourceBackend.php | 10 +++++++++- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php b/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php index 4ad275bc70f90..a3726207b3024 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php @@ -47,6 +47,8 @@ public function __construct( } /** + * Execute read handler for catalog product gallery + * * @param Product $entity * @param array $arguments * @return object @@ -69,6 +71,8 @@ public function execute($entity, $arguments = []) } /** + * Add media data to product + * * @param Product $product * @param array $mediaEntries * @return void @@ -86,6 +90,8 @@ public function addMediaDataToProduct(Product $product, array $mediaEntries) } /** + * Get attribute + * * @return \Magento\Catalog\Api\Data\ProductAttributeInterface * @since 101.0.0 */ @@ -99,6 +105,8 @@ public function getAttribute() } /** + * Find default value + * * @param string $key * @param string[] &$image * @return string diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php index b68c43e40ff2f..635715a60742f 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php @@ -49,7 +49,8 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc + * * @since 101.0.0 */ protected function _construct() @@ -58,7 +59,8 @@ protected function _construct() } /** - * {@inheritdoc} + * @inheritdoc + * * @since 101.0.0 */ public function getConnection() @@ -67,6 +69,8 @@ public function getConnection() } /** + * Load data from table by valueId + * * @param string $tableNameAlias * @param array $ids * @param int|null $storeId @@ -111,6 +115,8 @@ public function loadDataFromTableByValueId( } /** + * Load product gallery by attributeId + * * @param \Magento\Catalog\Model\Product $product * @param int $attributeId * @return array @@ -132,6 +138,8 @@ public function loadProductGalleryByAttributeId($product, $attributeId) } /** + * Create base load select + * * @param int $entityId * @param int $storeId * @param int $attributeId @@ -151,6 +159,8 @@ protected function createBaseLoadSelect($entityId, $storeId, $attributeId) } /** + * Create batch base select + * * @param int $storeId * @param int $attributeId * @return \Magento\Framework\DB\Select @@ -247,6 +257,8 @@ protected function removeDuplicates(&$result) } /** + * Get main table alias + * * @return string * @since 101.0.0 */ @@ -256,6 +268,8 @@ public function getMainTableAlias() } /** + * Bind value to entity + * * @param int $valueId * @param int $entityId * @return int @@ -273,6 +287,8 @@ public function bindValueToEntity($valueId, $entityId) } /** + * Save data row + * * @param string $table * @param array $data * @param array $fields diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php index 3611d95f0c6ac..feffd22a0fb3d 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php @@ -19,6 +19,9 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\DB\Adapter\AdapterInterface; +/** + * Configurable product resource model. + */ class Configurable extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { /** diff --git a/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php b/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php index 8a7e846c0e9f1..df8782ae422b4 100644 --- a/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php +++ b/app/code/Magento/ConfigurableProduct/Plugin/Catalog/Model/Product/Pricing/Renderer/SalableResolver.php @@ -27,8 +27,7 @@ public function __construct( } /** - * Performs an additional check whether given configurable product has - * at least one configuration in-stock. + * Performs an additional check whether given configurable product has at least one configuration in-stock. * * @param \Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolver $subject * @param bool $result diff --git a/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php b/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php index b27c7c8976b4c..04a3d868d14a6 100644 --- a/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php +++ b/app/code/Magento/ProductVideo/Model/Plugin/ExternalVideoResourceBackend.php @@ -27,6 +27,8 @@ public function __construct(\Magento\ProductVideo\Model\ResourceModel\Video $vid } /** + * Plugin for after duplicate action + * * @param Gallery $originalResourceModel * @param array $valueIdMap * @return array @@ -45,6 +47,8 @@ public function afterDuplicate(Gallery $originalResourceModel, array $valueIdMap } /** + * Plugin for after create batch base select action + * * @param Gallery $originalResourceModel * @param Select $select * @return Select @@ -62,7 +66,11 @@ public function afterCreateBatchBaseSelect(Gallery $originalResourceModel, Selec ), [] )->joinLeft( - ['default_value_video' => $originalResourceModel->getTable('catalog_product_entity_media_gallery_value_video')], + [ + 'default_value_video' => $originalResourceModel->getTable( + 'catalog_product_entity_media_gallery_value_video' + ) + ], implode( ' AND ', [ From 4328497e27f38c9317b4a2731b08fbd61243a5ae Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 13 Nov 2018 10:37:02 +0100 Subject: [PATCH 760/812] Adjusted API-functional tests for new limits --- .../Framework/QueryComplexityLimiterTest.php | 132 ++++++++++++++++-- 1 file changed, 121 insertions(+), 11 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php index 3304d9e6198f4..9bf223068e226 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php @@ -24,7 +24,7 @@ public function testQueryComplexityIsLimited() $query = <<<QUERY { -category(id: 2) { + category(id: 2) { products { items { name @@ -52,9 +52,15 @@ public function testQueryComplexityIsLimited() new_from_date tier_price manufacturer - thumbnail + thumbnail { + url + label + } sku - image + image { + url + label + } canonical_url updated_at created_at @@ -76,12 +82,18 @@ public function testQueryComplexityIsLimited() special_from_date special_to_date new_to_date - thumbnail + thumbnail { + url + label + } new_from_date tier_price manufacturer sku - image + image { + url + label + } canonical_url updated_at created_at @@ -111,9 +123,15 @@ public function testQueryComplexityIsLimited() new_from_date tier_price manufacturer - thumbnail + thumbnail { + url + label + } sku - image + image { + url + label + } canonical_url updated_at created_at @@ -139,7 +157,10 @@ public function testQueryComplexityIsLimited() tier_price manufacturer sku - image + image { + url + label + } canonical_url updated_at created_at @@ -160,13 +181,101 @@ public function testQueryComplexityIsLimited() name special_from_date special_to_date + price { + minimalPrice { + amount { + value + currency + } + } + maximalPrice { + amount { + value + currency + } + } + regularPrice { + amount { + value + currency + } + } + } + tier_price + special_price + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } new_to_date new_from_date tier_price manufacturer sku - image - thumbnail + image { + url + label + } + thumbnail { + url + label + } canonical_url updated_at created_at @@ -221,9 +330,10 @@ public function testQueryComplexityIsLimited() } } } + QUERY; - self::expectExceptionMessageRegExp('/Max query complexity should be 160 but got 169/'); + self::expectExceptionMessageRegExp('/Max query complexity should be 250 but got 252/'); $this->graphQlQuery($query); } From 436e3d3a6bf8179220747bef5cbdaeaaab4b730f Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Tue, 13 Nov 2018 12:58:32 +0300 Subject: [PATCH 761/812] MAGETWO-91725: Reward Points Balance Update Emails are not being sent when balance change initiated by store front - Fix webapi test --- .../Customer/Api/CustomerMetadataTest.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerMetadataTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerMetadataTest.php index f2632aa1481e4..3b1d431342988 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerMetadataTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerMetadataTest.php @@ -9,6 +9,7 @@ use Magento\Customer\Api\Data\CustomerInterface as Customer; use Magento\Customer\Model\Data\AttributeMetadata; use Magento\TestFramework\TestCase\WebapiAbstract; +use Magento\TestFramework\Helper\Bootstrap; /** * Class CustomerMetadataTest @@ -19,6 +20,19 @@ class CustomerMetadataTest extends WebapiAbstract const SERVICE_VERSION = "V1"; const RESOURCE_PATH = "/V1/attributeMetadata/customer"; + /** + * @var CustomerMetadataInterface + */ + private $customerMetadata; + + /** + * Execute per test initialization. + */ + public function setUp() + { + $this->customerMetadata = Bootstrap::getObjectManager()->create(CustomerMetadataInterface::class); + } + /** * Test retrieval of attribute metadata for the customer entity type. * @@ -200,8 +214,7 @@ public function testGetCustomAttributesMetadata() $attributeMetadata = $this->_webApiCall($serviceInfo); - // There are no default custom attributes. - $this->assertCount(0, $attributeMetadata); + $this->assertCount(count($this->customerMetadata->getCustomAttributesMetadata()), $attributeMetadata); } /** From 19c1f871b6bb1853ad960edfc3f6c8372c8a3e4f Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 13 Nov 2018 11:40:06 +0100 Subject: [PATCH 762/812] API-functional tests coverage --- .../Catalog/CategoryProductsCountTest.php | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryProductsCountTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryProductsCountTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryProductsCountTest.php new file mode 100644 index 0000000000000..eddd456a7b866 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryProductsCountTest.php @@ -0,0 +1,143 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Catalog; + +use Magento\TestFramework\TestCase\GraphQlAbstract; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\Model\Product\Visibility; +use Magento\Catalog\Model\Product\Attribute\Source\Status as productStatus; + +/** + * Class CategoryProductsCountTest + * + * Test for Magento\CatalogGraphQl\Model\Resolver\Category\ProductsCount resolver + */ +class CategoryProductsCountTest extends GraphQlAbstract +{ + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $this->productRepository = $objectManager->create(ProductRepositoryInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testCategoryWithSaleableProduct() + { + $categoryId = 2; + + $query = <<<QUERY +{ + category(id: {$categoryId}) { + id + product_count + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertEquals(1, $response['category']['product_count']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/category_product.php + */ + public function testCategoryWithInvisibleProduct() + { + $categoryId = 333; + $sku = 'simple333'; + + $product = $this->productRepository->get($sku); + $product->setVisibility(Visibility::VISIBILITY_NOT_VISIBLE); + $this->productRepository->save($product); + + $query = <<<QUERY +{ + category(id: {$categoryId}) { + id + product_count + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertEquals(0, $response['category']['product_count']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_simple_out_of_stock.php + */ + public function testCategoryWithOutOfStockProductManageStockEnabled() + { + $categoryId = 2; + + $query = <<<QUERY +{ + category(id: {$categoryId}) { + id + product_count + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertEquals(0, $response['category']['product_count']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/category_product.php + */ + public function testCategoryWithOutOfStockProductManageStockDisabled() + { + $categoryId = 333; + + $query = <<<QUERY +{ + category(id: {$categoryId}) { + id + product_count + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertEquals(1, $response['category']['product_count']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/category_product.php + */ + public function testCategoryWithDisabledProduct() + { + $categoryId = 333; + $sku = 'simple333'; + + $product = $this->productRepository->get($sku); + $product->setStatus(ProductStatus::STATUS_DISABLED); + $this->productRepository->save($product); + + $query = <<<QUERY +{ + category(id: {$categoryId}) { + id + product_count + } +} +QUERY; + $response = $this->graphQlQuery($query); + + self::assertEquals(0, $response['category']['product_count']); + } +} From c683dde7e44b30c81f55593c9275eb1f31dc7cb1 Mon Sep 17 00:00:00 2001 From: "Lopukhov, Stanislav" <lopukhov@adobe.com> Date: Tue, 13 Nov 2018 13:09:09 +0200 Subject: [PATCH 763/812] MAGETWO-96118: Few optimizations on category & product pages --- app/code/Magento/Catalog/etc/db_schema.xml | 2 +- app/code/Magento/Catalog/etc/db_schema_whitelist.json | 2 +- .../Model/Product/Type/ConfigurableTest.php | 9 +++++++-- .../Framework/Interception/PluginList/PluginList.php | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index 8dcc623dd64dd..17e3dddc41c3b 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -835,7 +835,7 @@ <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID" indexType="btree"> <column name="value_id"/> </index> - <index referenceId="CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID_VALUE_ID_STORE_ID" indexType="btree"> + <index referenceId="CAT_PRD_ENTT_MDA_GLR_VAL_ENTT_ID_VAL_ID_STORE_ID" indexType="btree"> <column name="entity_id"/> <column name="value_id"/> <column name="store_id"/> diff --git a/app/code/Magento/Catalog/etc/db_schema_whitelist.json b/app/code/Magento/Catalog/etc/db_schema_whitelist.json index 31620e4e920f4..d4bd6927d4345 100644 --- a/app/code/Magento/Catalog/etc/db_schema_whitelist.json +++ b/app/code/Magento/Catalog/etc/db_schema_whitelist.json @@ -485,7 +485,7 @@ "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_STORE_ID": true, "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID": true, "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_VALUE_ID": true, - "CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_ENTITY_ID_VALUE_ID_STORE_ID": true + "CAT_PRD_ENTT_MDA_GLR_VAL_ENTT_ID_VAL_ID_STORE_ID": true }, "constraint": { "PRIMARY": true, diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php index bdb36b93af21c..78fa4733a2562 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ +// @codingStandardsIgnoreFile + namespace Magento\ConfigurableProduct\Model\Product\Type; use Magento\Catalog\Api\Data\ProductInterface; @@ -128,6 +130,10 @@ public function testGetUsedProductAttributes() $this->assertEquals($testConfigurable->getData(), $attributes[$attributeId]->getData()); } + /** + * @magentoAppIsolation enabled + * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + */ public function testGetConfigurableAttributes() { $collection = $this->model->getConfigurableAttributes($this->product); @@ -332,8 +338,7 @@ public function testGetSelectedAttributesInfo() $attribute = reset($attributes); $optionValueId = $attribute['values'][0]['value_index']; - $product->addCustomOption( - 'attributes', + $product->addCustomOption('attributes', $serializer->serialize([$attribute['attribute_id'] => $optionValueId]) ); diff --git a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php index e21841b48bc13..d20cd57f4e43f 100644 --- a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php +++ b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php @@ -264,7 +264,7 @@ public function getPlugin($type, $code) public function getNext($type, $method, $code = '__self') { $this->_loadScopedData(); - if (!isset($this->_inherited[$type]) && !array_key_exists($type, $this->_inherited)) { + if ($this->_inherited !== null && !isset($this->_inherited[$type]) && !array_key_exists($type, $this->_inherited)) { $this->_inheritPlugins($type); } $key = $type . '_' . lcfirst($method) . '_' . $code; From f4a0e6a6e0f484c6a5d4c469fdd84f027aa4aac8 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Tue, 13 Nov 2018 14:29:42 +0300 Subject: [PATCH 764/812] MAGETWO-62728: My Wishlist - quantity input box issue - Fixed static test; --- .../Wishlist/view/frontend/templates/item/column/cart.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml index 7578774fabc2c..848c6a76393f8 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/cart.phtml @@ -22,7 +22,7 @@ $allowedQty = $block->getMinMaxQty(); <div class="field qty"> <label class="label" for="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]"><span><?= $block->escapeHtml(__('Qty')) ?></span></label> <div class="control"> - <input type="number" data-role="qty" id="qty[<?= /* @noEscape */ $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true, 'validate-item-quantity':{'minAllowed':<?= $allowedQty['minAllowed'] ?>,'maxAllowed':<?= $allowedQty['maxAllowed'] ?>}}" + <input type="number" data-role="qty" id="qty[<?= /* @noEscape */ $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true, 'validate-item-quantity':{'minAllowed':<?= /* @noEscape */ $allowedQty['minAllowed'] ?>,'maxAllowed':<?= /* @noEscape */ $allowedQty['maxAllowed'] ?>}}" name="qty[<?= $block->escapeHtmlAttr($item->getId()) ?>]" value="<?= /* @noEscape */ (int)($block->getAddToCartQty($item) * 1) ?>"> </div> </div> From c4b394a43f6e2690c3706eb5c5768a69185584d5 Mon Sep 17 00:00:00 2001 From: "Lopukhov, Stanislav" <lopukhov@adobe.com> Date: Tue, 13 Nov 2018 13:56:45 +0200 Subject: [PATCH 765/812] MAGETWO-96118: Few optimizations on category & product pages --- .../Magento/Framework/Interception/PluginList/PluginList.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php index d20cd57f4e43f..e21841b48bc13 100644 --- a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php +++ b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php @@ -264,7 +264,7 @@ public function getPlugin($type, $code) public function getNext($type, $method, $code = '__self') { $this->_loadScopedData(); - if ($this->_inherited !== null && !isset($this->_inherited[$type]) && !array_key_exists($type, $this->_inherited)) { + if (!isset($this->_inherited[$type]) && !array_key_exists($type, $this->_inherited)) { $this->_inheritPlugins($type); } $key = $type . '_' . lcfirst($method) . '_' . $code; From 91157807e4e9bbb055b61d0f949535a816c172b6 Mon Sep 17 00:00:00 2001 From: "Lopukhov, Stanislav" <lopukhov@adobe.com> Date: Tue, 13 Nov 2018 13:59:36 +0200 Subject: [PATCH 766/812] MAGETWO-96118: Few optimizations on category & product pages --- .../Model/Product/Type/ConfigurableTest.php | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php index 5e9399ddd3d65..d1cf77f03a7bd 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php @@ -27,6 +27,7 @@ * @SuppressWarnings(PHPMD.LongVariable) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) + * @codingStandardsIgnoreFile */ class ConfigurableTest extends \PHPUnit\Framework\TestCase { @@ -154,8 +155,7 @@ protected function setUp() ->setMethods(['create']) ->getMock(); $this->productCollectionFactory = $this->getMockBuilder( - \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory::class - ) + \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory::class) ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); @@ -197,11 +197,6 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - $this->productFactory = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterfaceFactory::class) - ->setMethods(['create']) - ->disableOriginalConstructor() - ->getMock(); - $this->salableProcessor = $this->createMock(SalableProcessor::class); $this->model = $this->objectHelper->getObject( @@ -287,8 +282,7 @@ public function testSave() ->method('getData') ->willReturnMap($dataMap); $attribute = $this->getMockBuilder( - \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class - ) + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class) ->disableOriginalConstructor() ->setMethods(['addData', 'setStoreId', 'setProductId', 'save', '__wakeup', '__sleep']) ->getMock(); @@ -385,7 +379,7 @@ public function testGetUsedProducts() ['_cache_instance_used_product_attributes', null, []] ] ); - + $this->catalogConfig->expects($this->any())->method('getProductAttributes')->willReturn([]); $productCollection->expects($this->atLeastOnce())->method('addAttributeToSelect')->willReturnSelf(); $productCollection->expects($this->once())->method('setProductFilter')->willReturnSelf(); $productCollection->expects($this->atLeastOnce())->method('setFlag')->willReturnSelf(); @@ -471,8 +465,7 @@ public function testGetConfigurableAttributesAsArray($productStore) $eavAttribute->expects($this->atLeastOnce())->method('getStoreLabel')->willReturn('Store Label'); $attribute = $this->getMockBuilder( - \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class - ) + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class) ->disableOriginalConstructor() ->setMethods(['getProductAttribute', '__wakeup', '__sleep']) ->getMock(); @@ -515,17 +508,34 @@ public function getConfigurableAttributesAsArrayDataProvider() ]; } - public function testGetConfigurableAttributes() + public function testGetConfigurableAttributesNewProduct() { $configurableAttributes = '_cache_instance_configurable_attributes'; /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */ $product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) - ->setMethods(['getData', 'hasData', 'setData']) + ->setMethods(['hasData', 'getId']) ->disableOriginalConstructor() ->getMock(); $product->expects($this->once())->method('hasData')->with($configurableAttributes)->willReturn(false); + $product->expects($this->once())->method('getId')->willReturn(null); + + $this->assertEquals([], $this->model->getConfigurableAttributes($product)); + } + + public function testGetConfigurableAttributes() + { + $configurableAttributes = '_cache_instance_configurable_attributes'; + + /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */ + $product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + ->setMethods(['getData', 'hasData', 'setData', 'getId']) + ->disableOriginalConstructor() + ->getMock(); + + $product->expects($this->once())->method('hasData')->with($configurableAttributes)->willReturn(false); + $product->expects($this->once())->method('getId')->willReturn(1); $attributeCollection = $this->getMockBuilder(Collection::class) ->setMethods(['setProductFilter', 'orderByPosition', 'load']) @@ -582,8 +592,7 @@ public function testHasOptionsConfigurableAttribute() ->disableOriginalConstructor() ->getMock(); $attributeMock = $this->getMockBuilder( - \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class - ) + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class) ->disableOriginalConstructor() ->getMock(); From cbd6203d6505c5e366928dea5249b926a6a8bbb3 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 14:27:31 +0200 Subject: [PATCH 767/812] GraphQl-222: Apply changes from CR for PR 162 Fix static tests --- .../GraphQl/Exception/GraphQlAuthorizationException.php | 4 ++-- .../Framework/GraphQl/Exception/GraphQlInputException.php | 4 ++-- .../GraphQl/Exception/GraphQlNoSuchEntityException.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php index f71652edc63b3..f1232ebd4d14b 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php @@ -37,7 +37,7 @@ public function __construct(Phrase $phrase, \Exception $cause = null, $code = 0, } /** - * {@inheritDoc} + * @inheritdoc */ public function isClientSafe() : bool { @@ -45,7 +45,7 @@ public function isClientSafe() : bool } /** - * {@inheritDoc} + * @inheritdoc */ public function getCategory() : string { diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php index 6f97f06261358..429b7c04b7475 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php @@ -37,7 +37,7 @@ public function __construct(Phrase $phrase, \Exception $cause = null, $code = 0, } /** - * {@inheritDoc} + * @inheritdoc */ public function isClientSafe() : bool { @@ -45,7 +45,7 @@ public function isClientSafe() : bool } /** - * {@inheritDoc} + * @inheritdoc */ public function getCategory() : string { diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php index 4bd24d6cfd4a7..2a0b9d3bc2eaa 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php @@ -37,7 +37,7 @@ public function __construct(Phrase $phrase, \Exception $cause = null, $code = 0, } /** - * {@inheritDoc} + * @inheritdoc */ public function isClientSafe() : bool { @@ -45,7 +45,7 @@ public function isClientSafe() : bool } /** - * {@inheritDoc} + * @inheritdoc */ public function getCategory() : string { From 6062a1eae3d1ced249379daf4c77de711410b349 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 14:34:53 +0200 Subject: [PATCH 768/812] GraphQl: Missed PHPDoc argument headers in method graphQlQuery --- .../Magento/TestFramework/TestCase/GraphQlAbstract.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php index 9754a340900e2..790581c476da1 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php @@ -52,11 +52,14 @@ public function graphQlQuery( } /** + * Compose headers + * + * @param array $headers * @return string[] */ - private function composeHeaders($headers) + private function composeHeaders(array $headers): array { - $headersArray =[]; + $headersArray = []; foreach ($headers as $key => $value) { $headersArray[] = sprintf('%s: %s', $key, $value); } From 74fce4acb449bb2f3b31e4e93d876654c5f0f0ea Mon Sep 17 00:00:00 2001 From: Vlad Veselov <vlad.veselov@gmail.com> Date: Tue, 13 Nov 2018 14:50:30 +0200 Subject: [PATCH 769/812] Fix PHP Notice due to magento/magento2#18727 --- pub/index.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pub/index.php b/pub/index.php index 90b4778265447..d363951691d58 100644 --- a/pub/index.php +++ b/pub/index.php @@ -25,15 +25,14 @@ } $params = $_SERVER; -$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = array_replace_recursive( - $params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS], - [ +$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = + ($params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] ?? []) + + [ DirectoryList::PUB => [DirectoryList::URL_PATH => ''], DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'], DirectoryList::STATIC_VIEW => [DirectoryList::URL_PATH => 'static'], DirectoryList::UPLOAD => [DirectoryList::URL_PATH => 'media/upload'], - ] -); + ]; $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params); /** @var \Magento\Framework\App\Http $app */ $app = $bootstrap->createApplication(\Magento\Framework\App\Http::class); From 1378ed33cad3ab8fb4d121b700bfe53d8733c408 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 15:11:50 +0200 Subject: [PATCH 770/812] GraphQl-11: Alphabetize Schema Fields -- Fix static tests --- .../Magento/Framework/GraphQl/Config/GraphQlReaderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3d3372429123a..7f8996daa6e97 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/GraphQl/Config/GraphQlReaderTest.php @@ -194,7 +194,7 @@ enumValues(includeDeprecated: true) { $sortFields = ['inputFields', 'fields']; foreach ($sortFields as $sortField) { isset($searchTerm[$sortField]) && is_array($searchTerm[$sortField]) - ? usort($searchTerm[$sortField], function($a, $b) { + ? usort($searchTerm[$sortField], function ($a, $b) { $cmpField = 'name'; return isset($a[$cmpField]) && isset($b[$cmpField]) ? strcmp($a[$cmpField], $b[$cmpField]) : 0; From 7f61b6f9d20565d0338cd1f0a39afde7b9edaabd Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 15:39:59 +0200 Subject: [PATCH 771/812] GraphQl-222: Apply changes from CR for PR 162 - Fix API-functional tests --- .../GraphQl/Customer/AccountInformationTest.php | 2 +- .../GraphQl/Customer/RevokeCustomerTokenTest.php | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/AccountInformationTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/AccountInformationTest.php index 2caee84ba6f00..942e321a78718 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/AccountInformationTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/AccountInformationTest.php @@ -238,7 +238,7 @@ public function testUpdateAccountInformationIfCustomerIsLocked() /** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @expectedException \Exception - * @expectedExceptionMessage For changing "email" you should provide current "password". + * @expectedExceptionMessage Provide the current "password" to change "email". */ public function testUpdateEmailIfPasswordIsMissed() { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/RevokeCustomerTokenTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/RevokeCustomerTokenTest.php index 415a81f8cf45a..9bdbf3059eeaf 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/RevokeCustomerTokenTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/RevokeCustomerTokenTest.php @@ -23,7 +23,9 @@ public function testRevokeCustomerTokenValidCredentials() { $query = <<<QUERY mutation { - revokeCustomerToken + revokeCustomerToken { + result + } } QUERY; @@ -35,7 +37,7 @@ public function testRevokeCustomerTokenValidCredentials() $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; $response = $this->graphQlQuery($query, [], '', $headerMap); - $this->assertTrue($response['revokeCustomerToken']); + $this->assertTrue($response['revokeCustomerToken']['result']); } /** @@ -46,7 +48,9 @@ public function testRevokeCustomerTokenForGuestCustomer() { $query = <<<QUERY mutation { - revokeCustomerToken + revokeCustomerToken { + result + } } QUERY; $this->graphQlQuery($query, [], ''); From 7dba16ba0d61af22b241d58d99f026d0a140222f Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 15:55:47 +0200 Subject: [PATCH 772/812] GraphQl-39: Manage Shipping methods on Cart --- .../Address/AddressDataProvider.php | 2 +- .../{CartAddress.php => CartAddresses.php} | 24 ++----------------- .../Magento/QuoteGraphQl/etc/schema.graphqls | 2 +- 3 files changed, 4 insertions(+), 24 deletions(-) rename app/code/Magento/QuoteGraphQl/Model/{Resolver => Cart}/Address/AddressDataProvider.php (98%) rename app/code/Magento/QuoteGraphQl/Model/Resolver/{CartAddress.php => CartAddresses.php} (59%) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/AddressDataProvider.php similarity index 98% rename from app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php rename to app/code/Magento/QuoteGraphQl/Model/Cart/Address/AddressDataProvider.php index 80fe973c4e449..fb742477ec99b 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/Address/AddressDataProvider.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/AddressDataProvider.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\QuoteGraphQl\Model\Resolver\Address; +namespace Magento\QuoteGraphQl\Model\Cart\Address; use Magento\Framework\Api\ExtensibleDataObjectConverter; use Magento\Quote\Api\Data\AddressInterface; diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddresses.php similarity index 59% rename from app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php rename to app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddresses.php index 54bd8fa2a5717..69544672bf12e 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddress.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddresses.php @@ -11,14 +11,12 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Quote\Api\CartRepositoryInterface; -use Magento\Quote\Model\MaskedQuoteIdToQuoteId; -use Magento\QuoteGraphQl\Model\Resolver\Address\AddressDataProvider; +use Magento\QuoteGraphQl\Model\Cart\Address\AddressDataProvider; /** * @inheritdoc */ -class CartAddress implements ResolverInterface +class CartAddresses implements ResolverInterface { /** * @var AddressDataProvider @@ -26,29 +24,11 @@ class CartAddress implements ResolverInterface private $addressDataProvider; /** - * @var CartRepositoryInterface - */ - private $cartRepository; - - /** - * @var MaskedQuoteIdToQuoteId - */ - private $maskedQuoteIdToQuoteId; - - /** - * CartAddress constructor. - * - * @param MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId - * @param CartRepositoryInterface $cartRepository * @param AddressDataProvider $addressDataProvider */ public function __construct( - MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId, - CartRepositoryInterface $cartRepository, AddressDataProvider $addressDataProvider ) { - $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; - $this->cartRepository = $cartRepository; $this->addressDataProvider = $addressDataProvider; } diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index ce982952f1aee..a6c56318d7a9a 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -95,7 +95,7 @@ type Cart { cart_id: String items: [CartItemInterface] applied_coupon: AppliedCoupon - addresses: [CartAddress]! @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartAddress") + addresses: [CartAddress]! @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartAddresses") } type CartAddress { From 4a8720485da929caa4301fdac430f91a3628d42d Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 16:18:08 +0200 Subject: [PATCH 773/812] GraphQl-39: Manage Shipping methods on Cart - Fix static tests --- .../Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php index 7f945dca2fd76..a630b2d07c7df 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingMethodOnCart.php @@ -98,4 +98,4 @@ public function execute(Quote $cart, int $cartAddressId, string $carrierCode, st throw new GraphQlInputException(__($exception->getMessage())); } } -} \ No newline at end of file +} From 889824ea3bedd2295678d4bd631473a82105ae68 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 13 Nov 2018 15:31:05 +0100 Subject: [PATCH 774/812] Increased allowed query complexity to 300 --- app/code/Magento/GraphQl/etc/di.xml | 2 +- .../Framework/QueryComplexityLimiterTest.php | 63 ++++++++++++++++++- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml index 914dcc78e49e1..b2083ea758e56 100644 --- a/app/code/Magento/GraphQl/etc/di.xml +++ b/app/code/Magento/GraphQl/etc/di.xml @@ -100,7 +100,7 @@ <type name="Magento\Framework\GraphQl\Query\QueryComplexityLimiter"> <arguments> <argument name="queryDepth" xsi:type="number">20</argument> - <argument name="queryComplexity" xsi:type="number">250</argument> + <argument name="queryComplexity" xsi:type="number">300</argument> </arguments> </type> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php index 9bf223068e226..352947714360a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Framework/QueryComplexityLimiterTest.php @@ -263,6 +263,66 @@ public function testQueryComplexityIsLimited() percentage_value website_id } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } + tier_prices { + customer_group_id + qty + percentage_value + website_id + } new_to_date new_from_date tier_price @@ -330,10 +390,9 @@ public function testQueryComplexityIsLimited() } } } - QUERY; - self::expectExceptionMessageRegExp('/Max query complexity should be 250 but got 252/'); + self::expectExceptionMessageRegExp('/Max query complexity should be 300 but got 302/'); $this->graphQlQuery($query); } From d84929a4241776521322ba3fc9521544639bd59c Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 13 Nov 2018 17:10:23 +0200 Subject: [PATCH 775/812] Fixed code style issue --- .../Test/Unit/Observer/CheckUserLoginBackendObserverTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php index 2d0a2a7e1c99a..415f022a7364d 100644 --- a/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php +++ b/app/code/Magento/Captcha/Test/Unit/Observer/CheckUserLoginBackendObserverTest.php @@ -107,7 +107,6 @@ public function requiredCaptchaDataProvider(): array ]; } - /** * Test check user login in backend with wrong captcha * From 770e0f84c8ef2965f71b732bd2d38c529a4ff442 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Tue, 13 Nov 2018 18:23:00 +0300 Subject: [PATCH 776/812] MAGETWO-62728: My Wishlist - quantity input box issue - Fexed DOC section for add-to-wishlist.js file; --- .../Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js index db5f77348b2c0..8a20d2925849a 100644 --- a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js +++ b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js @@ -188,7 +188,7 @@ define([ /** * Bind form submit. * - @param {boolean} isFileUploaded + * @param {boolean} isFileUploaded */ bindFormSubmit: function (isFileUploaded) { var self = this; From 9c9581306d7c92751f643101e482ab4e9e4a02fd Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 13 Nov 2018 16:40:54 +0100 Subject: [PATCH 777/812] Fixed travis test running condition --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 78b088c9d848d..bd2b94865cafd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,6 +64,6 @@ script: # The scripts for grunt/phpunit type tests - if [ $TEST_SUITE == "functional" ]; then dev/tests/functional/vendor/phpunit/phpunit/phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js"] && [ $TEST_SUITE != "api" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi + - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js"] && [ $TEST_SUITE != "graphql-api-functional" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi - if [ $TEST_SUITE == "js" ]; then grunt $GRUNT_COMMAND; fi - if [ $TEST_SUITE == "graphql-api-functional" ]; then phpunit -c dev/tests/api-functional; fi From 702353a0f32bc0b5d7cca708c90ec1839c983a8e Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Tue, 13 Nov 2018 10:12:17 -0600 Subject: [PATCH 778/812] MAGETWO-95589: [FT][Temando] Tests fail with enabled Temando extension --- .../Test/Mftf/Section/CheckoutShippingMethodsSection.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml index 56ed42fbfbbea..ab4b59fd67d03 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml @@ -13,6 +13,7 @@ <element name="firstShippingMethod" type="radio" selector="//*[@id='checkout-shipping-method-load']//input[@class='radio']"/> <element name="shippingMethodRow" type="text" selector=".form.methods-shipping table tbody tr"/> <element name="checkShippingMethodByName" type="radio" selector="//div[@id='checkout-shipping-method-load']//td[contains(., '{{var1}}')]/..//input" parameterized="true"/> + <element name="shippingMethodFlatRate" type="radio" selector="#checkout-shipping-method-load input[value='flatrate_flatrate']"/> <element name="shippingMethodRowByName" type="text" selector="//div[@id='checkout-shipping-method-load']//td[contains(., '{{var1}}')]/.." parameterized="true"/> <element name="shipHereButton" type="button" selector="//div/following-sibling::div/button[contains(@class, 'action-select-shipping-item')]"/> <element name="shippingMethodLoader" type="button" selector="//div[contains(@class, 'checkout-shipping-method')]/following-sibling::div[contains(@class, 'loading-mask')]"/> From 534da46ce569e8fd4c079bc5978c1959cb45f06c Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Tue, 13 Nov 2018 18:18:29 +0200 Subject: [PATCH 779/812] Travis integration tests timeout fix --- dev/travis/before_script.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index dbd9d1cd4fec1..20bc59d718f13 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -13,9 +13,9 @@ case $TEST_SUITE in test_set_list=$(find testsuite/* -maxdepth 1 -mindepth 1 -type d | sort) test_set_count=$(printf "$test_set_list" | wc -l) - test_set_size[1]=$(printf "%.0f" $(echo "$test_set_count*0.17" | bc)) #17% - test_set_size[2]=$(printf "%.0f" $(echo "$test_set_count*0.27" | bc)) #27% - test_set_size[3]=$((test_set_count-test_set_size[1]-test_set_size[2])) #56% + test_set_size[1]=$(printf "%.0f" $(echo "$test_set_count*0.13" | bc)) #13% + test_set_size[2]=$(printf "%.0f" $(echo "$test_set_count*0.30" | bc)) #30% + test_set_size[3]=$((test_set_count-test_set_size[1]-test_set_size[2])) #55% echo "Total = ${test_set_count}; Batch #1 = ${test_set_size[1]}; Batch #2 = ${test_set_size[2]}; Batch #3 = ${test_set_size[3]};"; echo "==> preparing integration testsuite on index $INTEGRATION_INDEX with set size of ${test_set_size[$INTEGRATION_INDEX]}" From afd128e53d475092d8fbdf0c2a65d9654fbef9a6 Mon Sep 17 00:00:00 2001 From: vitaliyboyko <v.boyko@atwix.com> Date: Tue, 13 Nov 2018 18:27:09 +0200 Subject: [PATCH 780/812] graphQl: removed redundant multishipping references --- .../Magento/QuoteGraphQl/etc/graphql/di.xml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml index e7417d657a0ea..86bc954ae4ac4 100644 --- a/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/QuoteGraphQl/etc/graphql/di.xml @@ -8,21 +8,4 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface" type="Magento\QuoteGraphQl\Model\Cart\SetShippingAddressOnCart" /> - <virtualType name="multishippingPaymentSpecification" type="Magento\Payment\Model\Method\Specification\Composite"> - <arguments> - <argument name="specifications" xsi:type="array"> - <item name="enabled" xsi:type="string">Magento\Multishipping\Model\Payment\Method\Specification\Enabled</item> - </argument> - </arguments> - </virtualType> - <type name="Magento\Multishipping\Block\Checkout\Billing"> - <arguments> - <argument name="paymentSpecification" xsi:type="object">multishippingPaymentSpecification</argument> - </arguments> - </type> - <type name="Magento\Multishipping\Model\Checkout\Type\Multishipping"> - <arguments> - <argument name="paymentSpecification" xsi:type="object">multishippingPaymentSpecification</argument> - </arguments> - </type> </config> From 702072502f924e380149709ecfe5247ff4a7d510 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Tue, 13 Nov 2018 19:16:27 +0200 Subject: [PATCH 781/812] GraphQL-43: [Query] My Account > My Wish List - Refactoring --- .../Model/ProductDataProvider.php} | 21 ++++- .../Model/Resolver/ProductResolver.php | 53 ++++++++++++ .../WishlistItemsProductsResolver.php | 56 ------------- .../Model/Resolver/WishlistItemsResolver.php | 81 ++++++++++++++----- .../Model/Resolver/WishlistResolver.php | 53 +++++++----- .../Model/WishlistDataProvider.php | 37 --------- .../Model/WishlistItemsDataProvider.php | 50 ------------ .../WishlistGraphQl/etc/schema.graphqls | 16 ++-- .../Magento/GraphQl/Wishlist/WishlistTest.php | 60 +++++++++----- 9 files changed, 214 insertions(+), 213 deletions(-) rename app/code/Magento/{WishlistGraphQl/Model/WishlistItemsProductDataProvider.php => CatalogGraphQl/Model/ProductDataProvider.php} (60%) create mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php delete mode 100644 app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php delete mode 100644 app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php delete mode 100644 app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php b/app/code/Magento/CatalogGraphQl/Model/ProductDataProvider.php similarity index 60% rename from app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php rename to app/code/Magento/CatalogGraphQl/Model/ProductDataProvider.php index 76df065a80702..0d38490407e7c 100644 --- a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsProductDataProvider.php +++ b/app/code/Magento/CatalogGraphQl/Model/ProductDataProvider.php @@ -5,23 +5,38 @@ */ declare(strict_types=1); -namespace Magento\WishlistGraphQl\Model; +namespace Magento\CatalogGraphQl\Model; use Magento\Catalog\Api\ProductRepositoryInterface; -class WishlistItemsProductDataProvider +/** + * Product data provider + * + * TODO: will be replaces on deferred mechanism + */ +class ProductDataProvider { /** * @var ProductRepositoryInterface */ private $productRepository; + /** + * @param ProductRepositoryInterface $productRepository + */ public function __construct(ProductRepositoryInterface $productRepository) { $this->productRepository = $productRepository; } - public function getProductDataById(int $productId) { + /** + * Get product data by id + * + * @param int $productId + * @return array + */ + public function getProductDataById(int $productId): array + { $product = $this->productRepository->getById($productId); $productData = $product->toArray(); $productData['model'] = $product; diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php new file mode 100644 index 0000000000000..b59582a189f60 --- /dev/null +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\WishlistGraphQl\Model\Resolver; + +use Magento\CatalogGraphQl\Model\ProductDataProvider; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Wishlist\Model\Item; + +/** + * Fetches the Product data according to the GraphQL schema + */ +class ProductResolver implements ResolverInterface +{ + /** + * @var ProductDataProvider + */ + private $productDataProvider; + + /** + * @param ProductDataProvider $productDataProvider + */ + public function __construct(ProductDataProvider $productDataProvider) + { + $this->productDataProvider = $productDataProvider; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['model'])) { + throw new LocalizedException(__('Missing key "model" in Wishlist Item value data')); + } + /** @var Item $wishlistItem */ + $wishlistItem = $value['model']; + + return $this->productDataProvider->getProductDataById($wishlistItem->getProductId()); + } +} diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php deleted file mode 100644 index 26ace0e849e3f..0000000000000 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsProductsResolver.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\WishlistGraphQl\Model\Resolver; - -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Framework\GraphQl\Query\Resolver\Value; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\WishlistGraphQl\Model\WishlistItemsProductDataProvider; - -class WishlistItemsProductsResolver implements ResolverInterface -{ - /** - * @var WishlistItemsProductDataProvider - */ - private $productDataProvider; - - public function __construct(WishlistItemsProductDataProvider $productDataProvider) - { - $this->productDataProvider = $productDataProvider; - } - - - /** - * Fetches the data from persistence models and format it according to the GraphQL schema. - * - * @param \Magento\Framework\GraphQl\Config\Element\Field $field - * @param ContextInterface $context - * @param ResolveInfo $info - * @param array|null $value - * @param array|null $args - * @throws \Exception - * @return mixed|Value - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ) { - if (!isset($value['product_id'])) { - throw new GraphQlInputException( - __('Missing key %1 in wishlist item data', ['product_id']) - ); - } - return $this->productDataProvider->getProductDataById($value['product_id']); - } -} diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php index 707618b10602d..033c63441e907 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php @@ -7,36 +7,46 @@ namespace Magento\WishlistGraphQl\Model\Resolver; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Wishlist\Model\ResourceModel\Item\Collection as WishlistItemCollection; +use Magento\Wishlist\Model\ResourceModel\Item\CollectionFactory as WishlistItemCollectionFactory; use Magento\Wishlist\Model\Item; -use Magento\WishlistGraphQl\Model\WishlistItemsDataProvider; +use Magento\Wishlist\Model\Wishlist; +/** + * Fetches the Wishlist Items data according to the GraphQL schema + */ class WishlistItemsResolver implements ResolverInterface { /** - * @var WishlistItemsDataProvider + * @var WishlistItemCollectionFactory */ - private $wishlistItemsDataProvider; + private $wishlistItemCollectionFactory; - public function __construct(WishlistItemsDataProvider $wishlistItemsDataProvider) - { - $this->wishlistItemsDataProvider = $wishlistItemsDataProvider; + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @param WishlistItemCollectionFactory $wishlistItemCollectionFactory + * @param StoreManagerInterface $storeManager + */ + public function __construct( + WishlistItemCollectionFactory $wishlistItemCollectionFactory, + StoreManagerInterface $storeManager + ) { + $this->wishlistItemCollectionFactory = $wishlistItemCollectionFactory; + $this->storeManager = $storeManager; } /** - * Fetches the data from persistence models and format it according to the GraphQL schema. - * - * @param \Magento\Framework\GraphQl\Config\Element\Field $field - * @param ContextInterface $context - * @param ResolveInfo $info - * @param array|null $value - * @param array|null $args - * @throws \Exception - * @return mixed|Value + * @inheritdoc */ public function resolve( Field $field, @@ -45,14 +55,41 @@ public function resolve( array $value = null, array $args = null ) { - return array_map(function (Item $wishlistItem) { - return [ + if (!isset($value['model'])) { + throw new LocalizedException(__('Missing key "model" in Wishlist value data')); + } + /** @var Wishlist $wishlist */ + $wishlist = $value['model']; + + $wishlistItems = $this->getWishListItems($wishlist); + + $data = []; + foreach ($wishlistItems as $wishlistItem) { + $data[] = [ 'id' => $wishlistItem->getId(), 'qty' => $wishlistItem->getData('qty'), - 'description' => (string)$wishlistItem->getDescription(), + 'description' => $wishlistItem->getDescription(), 'added_at' => $wishlistItem->getAddedAt(), - 'product_id' => (int)$wishlistItem->getProductId() + 'model' => $wishlistItem, ]; - }, $this->wishlistItemsDataProvider->getWishlistItemsForCustomer($context->getUserId())); + } + return $data; + } + + /** + * @param Wishlist $wishlist + * @return Item[] + */ + private function getWishListItems(Wishlist $wishlist): array + { + /** @var WishlistItemCollection $wishlistItemCollection */ + $wishlistItemCollection = $this->wishlistItemCollectionFactory->create(); + $wishlistItemCollection + ->addWishlistFilter($wishlist) + ->addStoreFilter(array_map(function (StoreInterface $store) { + return $store->getId(); + }, $this->storeManager->getStores())) + ->setVisibilityFilter(); + return $wishlistItemCollection->getItems(); } } diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php index ba1a6e935c10e..e3a788af2ea7e 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistResolver.php @@ -8,34 +8,39 @@ namespace Magento\WishlistGraphQl\Model\Resolver; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\WishlistGraphQl\Model\WishlistDataProvider; +use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel; +use Magento\Wishlist\Model\Wishlist; +use Magento\Wishlist\Model\WishlistFactory; +/** + * Fetches the Wishlist data according to the GraphQL schema + */ class WishlistResolver implements ResolverInterface { /** - * @var WishlistDataProvider + * @var WishlistResourceModel + */ + private $wishlistResource; + + /** + * @var WishlistFactory */ - private $wishlistDataProvider; + private $wishlistFactory; - public function __construct(WishlistDataProvider $wishlistDataProvider) + /** + * @param WishlistResourceModel $wishlistResource + * @param WishlistFactory $wishlistFactory + */ + public function __construct(WishlistResourceModel $wishlistResource, WishlistFactory $wishlistFactory) { - $this->wishlistDataProvider = $wishlistDataProvider; + $this->wishlistResource = $wishlistResource; + $this->wishlistFactory = $wishlistFactory; } /** - * Fetches the data from persistence models and format it according to the GraphQL schema. - * - * @param \Magento\Framework\GraphQl\Config\Element\Field $field - * @param ContextInterface $context - * @param ResolveInfo $info - * @param array|null $value - * @param array|null $args - * @throws \Exception - * @return mixed|Value + * @inheritdoc */ public function resolve( Field $field, @@ -44,10 +49,22 @@ public function resolve( array $value = null, array $args = null ) { - $wishlist = $this->wishlistDataProvider->getWishlistForCustomer($context->getUserId()); + $customerId = $context->getUserId(); + + /** @var Wishlist $wishlist */ + $wishlist = $this->wishlistFactory->create(); + $this->wishlistResource->load($wishlist, $customerId, 'customer_id'); + + if (null === $wishlist->getId()) { + return []; + } + return [ 'sharing_code' => $wishlist->getSharingCode(), - 'updated_at' => $wishlist->getUpdatedAt() + 'updated_at' => $wishlist->getUpdatedAt(), + 'items_count' => $wishlist->getItemsCount(), + 'name' => $wishlist->getName(), + 'model' => $wishlist, ]; } } diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.php deleted file mode 100644 index a62ddebd91120..0000000000000 --- a/app/code/Magento/WishlistGraphQl/Model/WishlistDataProvider.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\WishlistGraphQl\Model; - -use Magento\Wishlist\Model\ResourceModel\Wishlist; -use Magento\Wishlist\Model\WishlistFactory; - -class WishlistDataProvider -{ - /** - * @var Wishlist - */ - private $wishlistResource; - /** - * @var WishlistFactory - */ - private $wishlistFactory; - - public function __construct(Wishlist $wishlistResource, WishlistFactory $wishlistFactory) - { - $this->wishlistResource = $wishlistResource; - $this->wishlistFactory = $wishlistFactory; - } - - public function getWishlistForCustomer(int $customerId): \Magento\Wishlist\Model\Wishlist - { - /** @var \Magento\Wishlist\Model\Wishlist $wishlist */ - $wishlist = $this->wishlistFactory->create(); - $this->wishlistResource->load($wishlist, $customerId, 'customer_id'); - return $wishlist; - } -} diff --git a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php b/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php deleted file mode 100644 index ca87b23460fc7..0000000000000 --- a/app/code/Magento/WishlistGraphQl/Model/WishlistItemsDataProvider.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\WishlistGraphQl\Model; - -use Magento\Store\Api\Data\StoreInterface; -use Magento\Store\Model\StoreManagerInterface; -use Magento\Wishlist\Model\Item; -use Magento\Wishlist\Model\ResourceModel\Item\CollectionFactory as WishlistItemCollectionFactory; - -class WishlistItemsDataProvider -{ - - /** - * @var WishlistItemCollectionFactory - */ - private $wishlistItemCollectionFactory; - /** - * @var StoreManagerInterface - */ - private $storeManager; - - public function __construct( - WishlistItemCollectionFactory $wishlistItemCollectionFactory, - StoreManagerInterface $storeManager - ) { - $this->wishlistItemCollectionFactory = $wishlistItemCollectionFactory; - $this->storeManager = $storeManager; - } - - /** - * @param int $customerId - * @return Item[] - */ - public function getWishlistItemsForCustomer(int $customerId): array - { - $wishlistItemCollection = $this->wishlistItemCollectionFactory->create(); - $wishlistItemCollection->addCustomerIdFilter($customerId); - $wishlistItemCollection->addStoreFilter(array_map(function (StoreInterface $store) { - return $store->getId(); - }, $this->storeManager->getStores())); - $wishlistItemCollection->setVisibilityFilter(); - $wishlistItemCollection->load(); - return $wishlistItemCollection->getItems(); - } -} diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index 5c6d701138560..a63ec6eff6f5b 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -7,14 +7,16 @@ type Query { type WishlistOutput { items: [WishlistItem] @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsResolver") @doc(description: "todo"), - sharing_code: String! @doc(description: "todo"), - updated_at: String! @doc(description: "todo") + items_count: Int @doc(description: "todo"), + name: String @doc(description: "todo"), + sharing_code: String @doc(description: "todo"), + updated_at: String @doc(description: "todo") } type WishlistItem { - id: Int! @doc(description: "todo") - qty: Float! @doc(description: "todo"), - description: String! @doc(description: "todo"), - added_at: String! @doc(description: "todo"), - product: ProductInterface @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsProductsResolver") + id: Int @doc(description: "todo") + qty: Float @doc(description: "todo"), + description: String @doc(description: "todo"), + added_at: String @doc(description: "todo"), + product: ProductInterface @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\ProductResolver") } \ No newline at end of file diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php index 53577d02df50f..d570fc09b7714 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/WishlistTest.php @@ -8,40 +8,45 @@ namespace Magento\GraphQl\Wishlist; use Magento\Integration\Api\CustomerTokenServiceInterface; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; use Magento\Wishlist\Model\Item; +use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel; +use Magento\Wishlist\Model\WishlistFactory; class WishlistTest extends GraphQlAbstract { - /** - * @var \Magento\TestFramework\ObjectManager - */ - private $objectManager; /** * @var CustomerTokenServiceInterface */ private $customerTokenService; + /** + * @var WishlistFactory + */ + private $wishlistFactory; + + /** + * @var WishlistResourceModel + */ + private $wishlistResource; + protected function setUp() { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->customerTokenService = $this->objectManager->get(CustomerTokenServiceInterface::class); + $this->customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class); + $this->wishlistFactory = Bootstrap::getObjectManager()->get(WishlistFactory::class); + $this->wishlistResource = Bootstrap::getObjectManager()->get(WishlistResourceModel::class); } /** - * Verify the fields of CMS Block selected by identifiers - * * @magentoApiDataFixture Magento/Wishlist/_files/wishlist.php - * @throws \Magento\Framework\Exception\AuthenticationException - * @throws \Exception */ - public function testGetCustomersWishlist(): void + public function testGetCustomerWishlist(): void { /** @var \Magento\Wishlist\Model\Wishlist $wishlist */ - $wishlist = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Wishlist\Model\Wishlist::class - ); - $wishlist->loadByCustomerId(1, true); + $wishlist = $this->wishlistFactory->create(); + $this->wishlistResource->load($wishlist, 1, 'customer_id'); + /** @var Item $wishlistItem */ $wishlistItem = $wishlist->getItemCollection()->getFirstItem(); $wishlistItemProduct = $wishlistItem->getProduct(); @@ -49,26 +54,41 @@ public function testGetCustomersWishlist(): void <<<QUERY { wishlist { + items_count + name + sharing_code + updated_at items { id qty + description + added_at product { sku name } - description - added_at } - sharing_code - updated_at } } QUERY; - $response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders('customer@example.com', 'password')); + $response = $this->graphQlQuery( + $query, + [], + '', + $this->getCustomerAuthHeaders('customer@example.com', 'password') + ); + + $this->assertEquals($wishlist->getItemsCount(), $response['wishlist']['items_count']); + $this->assertEquals($wishlist->getName(), $response['wishlist']['name']); $this->assertEquals($wishlist->getSharingCode(), $response['wishlist']['sharing_code']); + $this->assertEquals($wishlist->getUpdatedAt(), $response['wishlist']['updated_at']); + + $this->assertEquals($wishlistItem->getId(), $response['wishlist']['items'][0]['id']); $this->assertEquals($wishlistItem->getData('qty'), $response['wishlist']['items'][0]['qty']); $this->assertEquals($wishlistItem->getDescription(), $response['wishlist']['items'][0]['description']); + $this->assertEquals($wishlistItem->getAddedAt(), $response['wishlist']['items'][0]['added_at']); + $this->assertEquals($wishlistItemProduct->getSku(), $response['wishlist']['items'][0]['product']['sku']); $this->assertEquals($wishlistItemProduct->getName(), $response['wishlist']['items'][0]['product']['name']); } From 39fe0fa91f1eb7146af7f7d542f54dfc0f764b20 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Tue, 13 Nov 2018 13:28:48 -0600 Subject: [PATCH 782/812] MQE-1339: Bump MFTF version in Magento - MFTF version bump and lockfile update --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 44452b6b4745f..00e5767fb4d6a 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.13.0", "lusitanian/oauth": "~0.8.10", - "magento/magento2-functional-testing-framework": "2.3.10", + "magento/magento2-functional-testing-framework": "2.3.11", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index 3565ab2420e05..7ce9efeb65e6f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "94ba8bea0470c1e4599c17145dcf3508", + "content-hash": "243bbfba7578f2084615fa0c092f87a8", "packages": [ { "name": "braintree/braintree_php", @@ -6351,16 +6351,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.3.10", + "version": "2.3.11", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "7cd80dbf1af405473f1a976c3b75097a0f27725d" + "reference": "3ca1bd74228a61bd05520bed1ef88b5a19764d92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/7cd80dbf1af405473f1a976c3b75097a0f27725d", - "reference": "7cd80dbf1af405473f1a976c3b75097a0f27725d", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/3ca1bd74228a61bd05520bed1ef88b5a19764d92", + "reference": "3ca1bd74228a61bd05520bed1ef88b5a19764d92", "shasum": "" }, "require": { @@ -6418,7 +6418,7 @@ "magento", "testing" ], - "time": "2018-11-06T20:54:16+00:00" + "time": "2018-11-13T18:22:25+00:00" }, { "name": "moontoast/math", From d3078dbd147a6fb30592370256f34c84f078fa33 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 14 Nov 2018 10:17:15 +0300 Subject: [PATCH 783/812] MAGETWO-71022: After return "RMA" is complete in Admin, "remaining quantity" in customer account shows incorrect value - Stabilize test --- .../Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml index 4ab1e3327960c..00f290cd94e70 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml @@ -13,5 +13,6 @@ <element name="email" type="input" selector="#email"/> <element name="requiredGroup" type="text" selector=".admin__field.required[data-ui-id='billing-address-fieldset-element-form-field-group-id']"/> <element name="requiredEmail" type="text" selector=".admin__field.required[data-ui-id='billing-address-fieldset-element-form-field-email']"/> + <element name="defaultGeneral" type="text" selector="//*[text()='Default (General)']" time="15"/> </section> </sections> \ No newline at end of file From 0acab420008a958fcbbb635cd0317681a5f06309 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <Veronika_Kurochkina@epam.com> Date: Wed, 14 Nov 2018 11:14:58 +0300 Subject: [PATCH 784/812] MAGETWO-62728: My Wishlist - quantity input box issue - Fix static tests --- .../Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js index 8a20d2925849a..cab130f7c2104 100644 --- a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js +++ b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js @@ -188,7 +188,7 @@ define([ /** * Bind form submit. * - * @param {boolean} isFileUploaded + * @param {Boolean} isFileUploaded */ bindFormSubmit: function (isFileUploaded) { var self = this; @@ -199,6 +199,7 @@ define([ if (!$($(self.options.qtyInfo).closest('form')).valid()) { event.stopPropagation(); event.preventDefault(); + return; } From 66fb58bc8acbf04083bf6d332b5d83a9906e42a6 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Wed, 14 Nov 2018 16:02:45 +0200 Subject: [PATCH 785/812] GraphQl-41: [Query] My Account > My Orders -- Update composer files --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 7ce9efeb65e6f..2e1b77fe0a3c9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "243bbfba7578f2084615fa0c092f87a8", + "content-hash": "4f2fd2e8ffcc003e0a4a4116ec84b780", "packages": [ { "name": "braintree/braintree_php", From ce025fba563445590da3ca6f4d4d6caa5692ff34 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Wed, 14 Nov 2018 16:22:55 +0200 Subject: [PATCH 786/812] GraphQL-43: [Query] My Account > My Wish List - Update composer files --- app/code/Magento/WishlistGraphQl/composer.json | 1 + composer.lock | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/WishlistGraphQl/composer.json b/app/code/Magento/WishlistGraphQl/composer.json index 9226ea1754e6a..e0f342174f879 100644 --- a/app/code/Magento/WishlistGraphQl/composer.json +++ b/app/code/Magento/WishlistGraphQl/composer.json @@ -6,6 +6,7 @@ "php": "~7.1.3||~7.2.0", "magento/framework": "*", "magento/module-catalog": "*", + "magento/module-catalog-graph-ql": "*", "magento/module-wishlist": "*", "magento/module-store": "*" }, diff --git a/composer.lock b/composer.lock index d4ac4fc091bbc..bbc15bd96073b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "78153b5c8150c0d145b3372a534a45eb", + "content-hash": "18b533cc6fd96cad7b777d61edf94bd4", "packages": [ { "name": "braintree/braintree_php", From 0a12f2facafd2eaea06a208173cf1e564e107a19 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Wed, 14 Nov 2018 18:00:59 -0600 Subject: [PATCH 787/812] ENGCOM-3450: [Forwardport] Fixed tierprice discount not calculated correctly if has specialprice #19179 --- .../Catalog/Model/Product/Attribute/Backend/Tierprice.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php index 23b2dfa01bfbd..e346c912dccaa 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -13,6 +13,9 @@ use Magento\Catalog\Model\Attribute\ScopeOverriddenValue; +/** + * Backend model for Tierprice attribute + */ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPrice\AbstractGroupPrice { /** @@ -186,6 +189,10 @@ protected function modifyPriceData($object, $data) } /** + * Update Price values in DB + * + * Updates price values in DB from array comparing to old values. Returns bool if updated + * * @param array $valuesToUpdate * @param array $oldValues * @return boolean From 03f0861a1be43c9d283c64ad31b804b715997d3a Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Thu, 15 Nov 2018 16:03:08 +0300 Subject: [PATCH 788/812] MAGETWO-71022: After return "RMA" is complete in Admin, "remaining quantity" in customer account shows incorrect value - Stabilize test --- .../Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml index 00f290cd94e70..11d973d1e19de 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormAccountSection.xml @@ -13,6 +13,6 @@ <element name="email" type="input" selector="#email"/> <element name="requiredGroup" type="text" selector=".admin__field.required[data-ui-id='billing-address-fieldset-element-form-field-group-id']"/> <element name="requiredEmail" type="text" selector=".admin__field.required[data-ui-id='billing-address-fieldset-element-form-field-email']"/> - <element name="defaultGeneral" type="text" selector="//*[text()='Default (General)']" time="15"/> + <element name="defaultGeneral" type="text" selector="//*[contains(text(),'General')]" time="15"/> </section> </sections> \ No newline at end of file From f8cbd49653e93a17a7d9a3997f0ea8d5b79aa48f Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 15 Nov 2018 15:14:41 +0200 Subject: [PATCH 789/812] GraphQL-43: [Query] My Account > My Wish List --- .../Magento/WishlistGraphQl/composer.json | 1 - .../WishlistGraphQl/etc/schema.graphqls | 20 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/WishlistGraphQl/composer.json b/app/code/Magento/WishlistGraphQl/composer.json index e0f342174f879..630ee97acc2eb 100644 --- a/app/code/Magento/WishlistGraphQl/composer.json +++ b/app/code/Magento/WishlistGraphQl/composer.json @@ -5,7 +5,6 @@ "require": { "php": "~7.1.3||~7.2.0", "magento/framework": "*", - "magento/module-catalog": "*", "magento/module-catalog-graph-ql": "*", "magento/module-wishlist": "*", "magento/module-store": "*" diff --git a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls index a63ec6eff6f5b..f5b5034fb734f 100644 --- a/app/code/Magento/WishlistGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WishlistGraphQl/etc/schema.graphqls @@ -2,21 +2,21 @@ # See COPYING.txt for license details. type Query { - wishlist: WishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistResolver") @doc(description: "todo") + wishlist: WishlistOutput @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistResolver") @doc(description: "The wishlist query returns the contents of a customer's wish list") } type WishlistOutput { - items: [WishlistItem] @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsResolver") @doc(description: "todo"), - items_count: Int @doc(description: "todo"), - name: String @doc(description: "todo"), - sharing_code: String @doc(description: "todo"), - updated_at: String @doc(description: "todo") + items: [WishlistItem] @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\WishlistItemsResolver") @doc(description: "An array of items in the customer's wish list"), + items_count: Int @doc(description: "The number of items in the wish list"), + name: String @doc(description: "When multiple wish lists are enabled, the name the customer assigns to the wishlist"), + sharing_code: String @doc(description: "An encrypted code that Magento uses to link to the wish list"), + updated_at: String @doc(description: "The time of the last modification to the wish list") } type WishlistItem { - id: Int @doc(description: "todo") - qty: Float @doc(description: "todo"), - description: String @doc(description: "todo"), - added_at: String @doc(description: "todo"), + id: Int @doc(description: "The wish list item ID") + qty: Float @doc(description: "The quantity of this wish list item"), + description: String @doc(description: "The customer's comment about this item"), + added_at: String @doc(description: "The time when the customer added the item to the wish list"), product: ProductInterface @resolver(class: "\\Magento\\WishlistGraphQl\\Model\\Resolver\\ProductResolver") } \ No newline at end of file From 31797246faf847433f9353ec61375f3adb51e531 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 15 Nov 2018 15:29:20 +0200 Subject: [PATCH 790/812] GraphQL-43: [Query] My Account > My Wish List - Update composer files --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 7ce9efeb65e6f..0af9477ff4ef9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "243bbfba7578f2084615fa0c092f87a8", + "content-hash": "b367db394f87f9f9006b40e36e5a4175", "packages": [ { "name": "braintree/braintree_php", From 52c5fba5b765dec8582ea527ce745fe77b7d2634 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Thu, 15 Nov 2018 13:24:42 +0300 Subject: [PATCH 791/812] MAGETWO-91496: Instantiating WYSIWYG in DynamicRows - Create parameter for suffix adding --- .../Magento/Ui/view/base/web/js/form/element/wysiwyg.js | 8 ++++++++ .../Magento/Framework/Data/Form/Element/Editor.php | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js index 235113b389fc7..070761fff53e3 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js @@ -80,6 +80,14 @@ define([ return config.name.replace(/(\.|-)/g, '_'); }, + /** + * @inheritdoc + */ + destroy: function () { + this._super(); + wysiwyg.removeEvents(this.wysiwygId); + }, + /** * * @returns {exports} diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Editor.php b/lib/internal/Magento/Framework/Data/Form/Element/Editor.php index dee0b6c842f5f..b5f2017501c01 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Editor.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Editor.php @@ -548,6 +548,7 @@ protected function getInlineJs($jsSetupObject, $forceLoad) */ public function getHtmlId() { - return parent::getHtmlId() . '${ $.wysiwygUniqueSuffix }'; + $suffix = $this->getConfig('dynamic_id') ? '${ $.wysiwygUniqueSuffix }' : ''; + return parent::getHtmlId() . $suffix; } } From adda7da9743ef8eb90f1d060e72d65bcdc7d0b40 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 15 Nov 2018 08:59:26 -0600 Subject: [PATCH 792/812] Revert "MQE-1267: Unskip Timezone Tests in Magento 2.3" - This reverts commit 0e0c110 --- .../Test/AdminApplyCatalogRuleByCategoryTest.xml | 3 +++ .../Mftf/Test/AdminCreateCatalogPriceRuleTest.xml | 15 +++++++++++++++ .../Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml | 3 +++ .../Test/StorefrontInactiveCatalogRuleTest.xml | 3 +++ 4 files changed, 24 insertions(+) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml index 741da96179b8c..716a363ec5d78 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml @@ -16,6 +16,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-74"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <createData entity="ApiCategory" stepKey="createCategoryOne"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml index befe0b0ce7f98..072385c46645a 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml @@ -17,6 +17,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-65"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <!-- Create the simple product and category that it will be in --> @@ -74,6 +77,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-93"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <actionGroup stepKey="createNewPriceRule" ref="newCatalogPriceRuleByUI"> @@ -97,6 +103,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-69"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <actionGroup stepKey="createNewPriceRule" ref="newCatalogPriceRuleByUI"> @@ -120,6 +129,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-60"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <actionGroup stepKey="createNewPriceRule" ref="newCatalogPriceRuleByUI"> @@ -143,6 +155,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-71"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <!-- Create a simple product and a category--> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml index d3546d06492be..83770ffff5eab 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleTest.xml @@ -17,6 +17,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-160"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml index e7be6e8443a36..55f775e40feaa 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml @@ -17,6 +17,9 @@ <severity value="CRITICAL"/> <testCaseId value="MC-79"/> <group value="CatalogRule"/> + <skip> + <issueId value="DEVOPS-3618"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="login"/> From db851ff49c3e8e6c49dce7d10c0a56a57020f9c4 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 15 Nov 2018 17:35:20 +0200 Subject: [PATCH 793/812] GraphQL-43: [Query] My Account > My Wish List - Update composer files --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 2e1b77fe0a3c9..36b4dca023191 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4f2fd2e8ffcc003e0a4a4116ec84b780", + "content-hash": "7538e15ea4ff1378cf55983ce9acba82", "packages": [ { "name": "braintree/braintree_php", From a0a150fce54acdbb6fc8fc85820972cd33ebdaa9 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <mankivsk@adobe.com> Date: Thu, 15 Nov 2018 12:00:53 -0600 Subject: [PATCH 794/812] #2340: Fixed static tests --- .../Magento/Bundle/Model/OptionRepository.php | 20 +++++++++++++------ .../Test/Unit/Model/OptionRepositoryTest.php | 3 ++- .../product_grouped_with_out_of_stock.php | 2 +- ...uct_grouped_with_out_of_stock_rollback.php | 2 +- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Bundle/Model/OptionRepository.php b/app/code/Magento/Bundle/Model/OptionRepository.php index 46c44c83b5bb5..0b96ea8d5b789 100644 --- a/app/code/Magento/Bundle/Model/OptionRepository.php +++ b/app/code/Magento/Bundle/Model/OptionRepository.php @@ -90,7 +90,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function get($sku, $optionId) { @@ -123,7 +123,7 @@ public function get($sku, $optionId) } /** - * {@inheritdoc} + * @inheritdoc */ public function getList($sku) { @@ -132,6 +132,8 @@ public function getList($sku) } /** + * Return list of product options + * * @param ProductInterface $product * @return \Magento\Bundle\Api\Data\OptionInterface[] */ @@ -141,7 +143,7 @@ public function getListByProduct(ProductInterface $product) } /** - * {@inheritdoc} + * @inheritdoc */ public function delete(\Magento\Bundle\Api\Data\OptionInterface $option) { @@ -157,7 +159,7 @@ public function delete(\Magento\Bundle\Api\Data\OptionInterface $option) } /** - * {@inheritdoc} + * @inheritdoc */ public function deleteById($sku, $optionId) { @@ -169,7 +171,7 @@ public function deleteById($sku, $optionId) } /** - * {@inheritdoc} + * @inheritdoc */ public function save( \Magento\Catalog\Api\Data\ProductInterface $product, @@ -189,6 +191,9 @@ public function save( * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param \Magento\Bundle\Api\Data\OptionInterface $option * @return $this + * @throws InputException + * @throws NoSuchEntityException + * @throws \Magento\Framework\Exception\CouldNotSaveException */ protected function updateOptionSelection( \Magento\Catalog\Api\Data\ProductInterface $product, @@ -228,9 +233,12 @@ protected function updateOptionSelection( } /** + * Retrieve product by SKU + * * @param string $sku * @return \Magento\Catalog\Api\Data\ProductInterface - * @throws \Magento\Framework\Exception\InputException + * @throws InputException + * @throws NoSuchEntityException */ private function getProduct($sku) { diff --git a/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php b/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php index c579d8289d1b6..2450f63c38933 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php @@ -280,7 +280,8 @@ public function testDeleteById() /** * Tests if NoSuchEntityException thrown when provided $optionId not found */ - public function testDeleteByIdException() { + public function testDeleteByIdException() + { $productSku = 'sku'; $optionId = null; diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php index 7aa62b149b8c0..369ce7d490eea 100644 --- a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php @@ -1,4 +1,4 @@ -\<?php +<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php index 48e7d495f8985..26a7487077e44 100644 --- a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php @@ -1,4 +1,4 @@ -\<?php +<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. From b7c25f3f60649c7f4f2f47e46d13a6f94aba552f Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 16 Nov 2018 16:23:12 +0200 Subject: [PATCH 795/812] GraphQL-43: [Query] My Account > My Wish List -- Fix static tests --- .../WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php | 2 ++ app/code/Magento/WishlistGraphQl/registration.php | 1 + 2 files changed, 3 insertions(+) diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php index 033c63441e907..dfbbf6543f66f 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/WishlistItemsResolver.php @@ -77,6 +77,8 @@ public function resolve( } /** + * Get wishlist items + * * @param Wishlist $wishlist * @return Item[] */ diff --git a/app/code/Magento/WishlistGraphQl/registration.php b/app/code/Magento/WishlistGraphQl/registration.php index f2047f225e5b6..c5d468421f96e 100644 --- a/app/code/Magento/WishlistGraphQl/registration.php +++ b/app/code/Magento/WishlistGraphQl/registration.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); use Magento\Framework\Component\ComponentRegistrar; From 370aaebbd95045ed4aaefa37592e4abf12869215 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 16 Nov 2018 18:31:05 +0200 Subject: [PATCH 796/812] GraphQL-43: [Query] My Account > My Wish List -- Fix API-functional tests --- .../Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php b/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php index b59582a189f60..65c8498fc89ad 100644 --- a/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php +++ b/app/code/Magento/WishlistGraphQl/Model/Resolver/ProductResolver.php @@ -48,6 +48,6 @@ public function resolve( /** @var Item $wishlistItem */ $wishlistItem = $value['model']; - return $this->productDataProvider->getProductDataById($wishlistItem->getProductId()); + return $this->productDataProvider->getProductDataById((int)$wishlistItem->getProductId()); } } From 0d58352a7924ba28c0ba159f5b806048dea974f8 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 16 Nov 2018 19:12:46 +0200 Subject: [PATCH 797/812] GraphQL-115: Travis api-functional tests automated execution introduced --- dev/travis/before_script.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev/travis/before_script.sh b/dev/travis/before_script.sh index 9f1edbf6c8a50..5d091efbb30a3 100755 --- a/dev/travis/before_script.sh +++ b/dev/travis/before_script.sh @@ -152,17 +152,17 @@ case $TEST_SUITE in --admin-use-security-key=0 \ --admin-password="123123q" - echo "Enabling production mode" - php bin/magento deploy:mode:set production - echo "Prepare api-functional tests for running" cd dev/tests/api-functional - cp -r _files/Magento/* ../../../app/code/Magento # Deploy and enable test modules before running tests + cp -r _files/Magento/TestModuleGraphQl* ../../../app/code/Magento # Deploy and enable test modules before running tests cp ./phpunit_graphql.xml.dist ./phpunit.xml sed -e "s?magento.url?${MAGENTO_HOST_NAME}?g" --in-place ./phpunit.xml cd ../../.. php bin/magento setup:upgrade + + echo "Enabling production mode" + php bin/magento deploy:mode:set production ;; esac From 4694c061b74e2d4e5c169480de7e855c3abc0a85 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 14:52:29 +0200 Subject: [PATCH 798/812] GraphQL-39: Manage Shipping methods on Cart --- .../Model/Cart/SetShippingAddressOnCart.php | 30 ++++++++++--------- .../SetShippingAddressesOnCartInterface.php | 3 +- .../Resolver/SetShippingAddressesOnCart.php | 2 +- app/code/Magento/QuoteGraphQl/composer.json | 3 +- .../Quote/SetShippingAddressOnCartTest.php | 2 +- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php index 960900682db4c..b9fd5c7807d2f 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php @@ -7,9 +7,8 @@ namespace Magento\QuoteGraphQl\Model\Cart; -use Magento\Authorization\Model\UserContextInterface; use Magento\Customer\Api\Data\AddressInterface; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccount; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Quote\Api\Data\CartInterface; @@ -37,19 +36,27 @@ class SetShippingAddressOnCart implements SetShippingAddressesOnCartInterface */ private $addressModel; + /** + * @var CheckCustomerAccount + */ + private $checkCustomerAccount; + /** * @param ShippingAddressManagementInterface $shippingAddressManagement * @param AddressRepositoryInterface $addressRepository * @param Address $addressModel + * @param CheckCustomerAccount $checkCustomerAccount */ public function __construct( ShippingAddressManagementInterface $shippingAddressManagement, AddressRepositoryInterface $addressRepository, - Address $addressModel + Address $addressModel, + CheckCustomerAccount $checkCustomerAccount ) { $this->shippingAddressManagement = $shippingAddressManagement; $this->addressRepository = $addressRepository; $this->addressModel = $addressModel; + $this->checkCustomerAccount = $checkCustomerAccount; } /** @@ -66,7 +73,7 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s $customerAddressId = $shippingAddress['customer_address_id'] ?? null; $addressInput = $shippingAddress['address'] ?? null; - if (!$customerAddressId && !$addressInput) { + if (null === $customerAddressId && null === $addressInput) { throw new GraphQlInputException( __('The shipping address must contain either "customer_address_id" or "address".') ); @@ -76,19 +83,14 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s __('The shipping address cannot contain "customer_address_id" and "address" at the same time.') ); } - if ($customerAddressId) { - if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { - throw new GraphQlAuthorizationException( - __( - 'Guest users cannot manage addresses.' - ) - ); - } + if (null === $customerAddressId) { + $shippingAddress = $this->addressModel->addData($addressInput); + } else { + $this->checkCustomerAccount->execute($context->getUserId(), $context->getUserType()); + /** @var AddressInterface $customerAddress */ $customerAddress = $this->addressRepository->getById($customerAddressId); $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); - } else { - $shippingAddress = $this->addressModel->addData($addressInput); } $this->shippingAddressManagement->assign($cart->getId(), $shippingAddress); diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php index dde9cce9d8693..c5da3db75add7 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCartInterface.php @@ -15,11 +15,10 @@ * Extension point for setting shipping addresses for a specified shopping cart * * All objects that are responsible for setting shipping addresses on a cart via GraphQl - *should implement this interface. + * should implement this interface. */ interface SetShippingAddressesOnCartInterface { - /** * Set shipping addresses for a specified shopping cart * diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php index 587ebb2b6db1f..b024e7b77af40 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php @@ -93,7 +93,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value return [ 'cart' => [ 'cart_id' => $maskedCartId, - 'model' => $cart + 'model' => $cart, ] ]; } diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 9d29cda3b872b..881450745b84a 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -9,8 +9,7 @@ "magento/module-checkout": "*", "magento/module-catalog": "*", "magento/module-store": "*", - "magento/module-customer": "*", - "magento/module-authorization": "*" + "magento/module-customer": "*" }, "suggest": { "magento/module-graph-ql": "*" diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php index 2b4223cf67a89..a023d37895c23 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php @@ -139,7 +139,7 @@ public function testSetSavedShippingAddressOnCartByGuest() } } QUERY; - self::expectExceptionMessage('Guest users cannot manage addresses.'); + self::expectExceptionMessage('The current customer isn\'t authorized.'); $this->graphQlQuery($query); } From ac93407e2e12cc9d953574bc448e1830390de380 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 15:22:56 +0200 Subject: [PATCH 799/812] GraphQL-189: Replace GraphQlInputException on LocalizedException --- .../BundleGraphQl/Model/Resolver/BundleItemLinks.php | 4 ++-- .../BundleGraphQl/Model/Resolver/Options/Label.php | 4 ++-- .../Model/LayerFilterItemTypeResolverComposite.php | 6 ++---- .../Model/ProductLinkTypeResolverComposite.php | 8 ++------ .../Magento/CatalogGraphQl/Model/Resolver/Categories.php | 4 ++-- .../Model/Resolver/Category/Breadcrumbs.php | 4 ++-- .../Model/Resolver/Product/CanonicalUrl.php | 4 ++-- .../Model/Resolver/Product/EntityIdToId.php | 4 ++-- .../Model/Resolver/Product/MediaGalleryEntries.php | 4 ++-- .../CatalogGraphQl/Model/Resolver/Product/NewFromTo.php | 4 ++-- .../CatalogGraphQl/Model/Resolver/Product/Options.php | 4 ++-- .../CatalogGraphQl/Model/Resolver/Product/Price.php | 4 ++-- .../Resolver/Product/ProductComplexTextAttribute.php | 4 ++-- .../Model/Resolver/Product/ProductLinks.php | 4 ++-- .../CatalogGraphQl/Model/Resolver/Product/TierPrices.php | 4 ++-- .../CatalogGraphQl/Model/Resolver/Product/Websites.php | 4 ++-- .../Model/Resolver/OnlyXLeftInStockResolver.php | 4 ++-- .../Model/Resolver/StockStatusProvider.php | 4 ++-- .../Model/Resolver/Product/DownloadableOptions.php | 4 ++-- .../EavGraphQl/Model/Resolver/AttributeOptions.php | 9 +++++---- .../Magento/EavGraphQl/Model/Resolver/Query/Type.php | 3 +-- app/code/Magento/GraphQl/Model/EntityAttributeList.php | 6 +++--- .../Model/Resolver/GroupedItems.php | 4 ++-- .../UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php | 4 ++-- 24 files changed, 51 insertions(+), 57 deletions(-) diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php index f55028a7d1a5b..184f7177a995c 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/BundleItemLinks.php @@ -7,7 +7,7 @@ namespace Magento\BundleGraphQl\Model\Resolver; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\BundleGraphQl\Model\Resolver\Links\Collection; use Magento\Framework\GraphQl\Config\Element\Field; @@ -47,7 +47,7 @@ public function __construct( public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { if (!isset($value['option_id']) || !isset($value['parent_id'])) { - throw new GraphQlInputException(__('"option_id" and "parent_id" values should be specified')); + throw new LocalizedException(__('"option_id" and "parent_id" values should be specified')); } $this->linkCollection->addIdFilters((int)$value['option_id'], (int)$value['parent_id']); diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Label.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Label.php index bcddd5d084629..de72b18982c12 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Label.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Options/Label.php @@ -7,7 +7,7 @@ namespace Magento\BundleGraphQl\Model\Resolver\Options; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product as ProductDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; @@ -50,7 +50,7 @@ public function resolve( array $args = null ) { if (!isset($value['sku'])) { - throw new GraphQlInputException(__('"sku" value should be specified')); + throw new LocalizedException(__('"sku" value should be specified')); } $this->product->addProductSku($value['sku']); diff --git a/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php b/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php index e04b5d1bf67ff..02594ecfaf8e8 100644 --- a/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/LayerFilterItemTypeResolverComposite.php @@ -31,7 +31,7 @@ public function __construct(array $typeResolvers = []) } /** - * {@inheritdoc} + * @inheritdoc */ public function resolveType(array $data) : string { @@ -42,8 +42,6 @@ public function resolveType(array $data) : string return $resolvedType; } } - if (empty($resolvedType)) { - throw new \LogicException('Cannot resolve layered filter type'); - } + throw new GraphQlInputException(__('Cannot resolve layered filter type')); } } diff --git a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php index 5f6d1a65519f8..fbce18dfb67a5 100644 --- a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php @@ -29,8 +29,7 @@ public function __construct(array $productLinksTypeNameResolvers = []) } /** - * {@inheritdoc} - * @throws GraphQlInputException + * @inheritdoc */ public function resolveType(array $data) : string { @@ -48,9 +47,6 @@ public function resolveType(array $data) : string return $resolvedType; } } - - if (!$resolvedType) { - throw new \LogicException('Cannot resolve type'); - } + throw new GraphQlInputException(__('Cannot resolve type')); } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php index de4c7dd71ca36..cb392a7b2295d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Api\Data\CategoryInterface; use Magento\Catalog\Model\ResourceModel\Category\Collection; @@ -85,7 +85,7 @@ public function __construct( public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var \Magento\Catalog\Model\Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Breadcrumbs.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Breadcrumbs.php index 9e966a060e5c6..b93c7e279153d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Breadcrumbs.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Breadcrumbs.php @@ -8,7 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Category; use Magento\CatalogGraphQl\Model\Resolver\Category\DataProvider\Breadcrumbs as BreadcrumbsDataProvider; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -38,7 +38,7 @@ public function __construct( public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { if (!isset($value['path'])) { - throw new GraphQlInputException(__('"path" value should be specified')); + throw new LocalizedException(__('"path" value should be specified')); } $breadcrumbsData = $this->breadcrumbsDataProvider->getData($value['path']); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CanonicalUrl.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CanonicalUrl.php index 0f1a7d8ee9dab..9047eaee4b568 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CanonicalUrl.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/CanonicalUrl.php @@ -8,8 +8,8 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Catalog\Model\Product; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -29,7 +29,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /* @var $product Product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php index a09510be8bc7d..962256ceff442 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\Product; @@ -46,7 +46,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php index a54cb62c16527..785cd75585d5d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Framework\GraphQl\Config\Element\Field; @@ -31,7 +31,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php index 2fa47f86ecb9d..88ae457c9986f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Framework\GraphQl\Config\Element\Field; @@ -31,7 +31,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php index 7c7e4ef117a50..cb53ebdab4810 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Option; @@ -32,7 +32,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php index 6f4f8553a324a..3bc9057f06b01 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Pricing\Price\FinalPrice; @@ -59,7 +59,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php index 96519d6191eee..2573e92e564b9 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductComplexTextAttribute.php @@ -7,11 +7,11 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Catalog\Helper\Output as OutputHelper; /** @@ -44,7 +44,7 @@ public function resolve( array $args = null ): array { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /* @var $product Product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php index 4d5622bd5c6d0..b2a612d6ae02d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\ProductLink\Link; @@ -39,7 +39,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php index 63599a88c79a0..cf1b621ad65b6 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\TierPrice; @@ -34,7 +34,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Websites.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Websites.php index 9fe64a16935c7..070c564713a96 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Websites.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Websites.php @@ -7,7 +7,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; @@ -47,7 +47,7 @@ public function __construct( public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { if (!isset($value['entity_id'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } $this->productWebsitesCollection->addIdFilters((int)$value['entity_id']); $result = function () use ($value) { diff --git a/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/OnlyXLeftInStockResolver.php b/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/OnlyXLeftInStockResolver.php index 169456f7d4bbd..9e10f0b448504 100644 --- a/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/OnlyXLeftInStockResolver.php +++ b/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/OnlyXLeftInStockResolver.php @@ -11,7 +11,7 @@ use Magento\CatalogInventory\Api\StockRegistryInterface; use Magento\CatalogInventory\Model\Configuration; use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -50,7 +50,7 @@ public function __construct( public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { if (!array_key_exists('model', $value) || !$value['model'] instanceof ProductInterface) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /* @var $product ProductInterface */ diff --git a/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/StockStatusProvider.php b/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/StockStatusProvider.php index 2f3d520c2cb8f..354e053efa90f 100644 --- a/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/StockStatusProvider.php +++ b/app/code/Magento/CatalogInventoryGraphQl/Model/Resolver/StockStatusProvider.php @@ -10,7 +10,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\CatalogInventory\Api\Data\StockStatusInterface; use Magento\CatalogInventory\Api\StockStatusRepositoryInterface; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -39,7 +39,7 @@ public function __construct(StockStatusRepositoryInterface $stockStatusRepositor public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { if (!array_key_exists('model', $value) || !$value['model'] instanceof ProductInterface) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /* @var $product ProductInterface */ diff --git a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php index 5141361fecc0e..0842c96ef4b1a 100644 --- a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php +++ b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php @@ -7,7 +7,7 @@ namespace Magento\DownloadableGraphQl\Model\Resolver\Product; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Downloadable\Helper\Data as DownloadableHelper; @@ -77,7 +77,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var Product $product */ diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php b/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php index 6ccd610bead0d..b0def15f3a0d4 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php @@ -9,6 +9,7 @@ use Magento\EavGraphQl\Model\Resolver\DataProvider\AttributeOptions as AttributeOptionsDataProvider; use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\StateException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; @@ -68,12 +69,12 @@ public function resolve( /** * @param array $value * @return int - * @throws GraphQlInputException + * @throws LocalizedException */ private function getEntityType(array $value): int { if (!isset($value['entity_type'])) { - throw new GraphQlInputException(__('"Entity type should be specified')); + throw new LocalizedException(__('"Entity type should be specified')); } return (int)$value['entity_type']; @@ -82,12 +83,12 @@ private function getEntityType(array $value): int /** * @param array $value * @return string - * @throws GraphQlInputException + * @throws LocalizedException */ private function getAttributeCode(array $value): string { if (!isset($value['attribute_code'])) { - throw new GraphQlInputException(__('"Attribute code should be specified')); + throw new LocalizedException(__('"Attribute code should be specified')); } return $value['attribute_code']; diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php index b1d7aae5df101..390279f2cfe2e 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php @@ -9,7 +9,6 @@ use Magento\Framework\Webapi\CustomAttributeTypeLocatorInterface; use Magento\Framework\Reflection\TypeProcessor; -use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; /** @@ -71,7 +70,7 @@ public function getType(string $attributeCode, string $entityType) : string try { $type = $this->typeProcessor->translateTypeName($type); } catch (\InvalidArgumentException $exception) { - throw new \LogicException('Cannot resolve EAV type'); + throw new GraphQlInputException(__('Cannot resolve EAV type')); } } else { $type = $type === 'double' ? 'float' : $type; diff --git a/app/code/Magento/GraphQl/Model/EntityAttributeList.php b/app/code/Magento/GraphQl/Model/EntityAttributeList.php index 6b8a4f477069e..3802b74f3ec13 100644 --- a/app/code/Magento/GraphQl/Model/EntityAttributeList.php +++ b/app/code/Magento/GraphQl/Model/EntityAttributeList.php @@ -14,7 +14,7 @@ use Magento\Framework\Api\MetadataServiceInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; /** * Iterate through all attribute sets to retrieve attributes for any given entity type @@ -69,7 +69,7 @@ public function __construct( * @param string $entityCode * @param MetadataServiceInterface $metadataService * @return boolean[] - * @throws GraphQlInputException + * @throws GraphQlNoSuchEntityException */ public function getDefaultEntityAttributes( string $entityCode, @@ -93,7 +93,7 @@ public function getDefaultEntityAttributes( $this->attributeManagement->getAttributes($entityCode, $attributeSet->getAttributeSetId()) ); } catch (NoSuchEntityException $exception) { - throw new GraphQlInputException(__('Entity code %1 does not exist.', [$entityCode])); + throw new GraphQlNoSuchEntityException(__('Entity code %1 does not exist.', [$entityCode])); } } $attributeCodes = []; diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php index fee4063affef1..d51b22ffe21df 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/GroupedItems.php @@ -7,7 +7,7 @@ namespace Magento\GroupedProductGraphQl\Model\Resolver; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product; use Magento\Framework\GraphQl\Config\Element\Field; @@ -44,7 +44,7 @@ public function resolve( array $args = null ) { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } $data = []; diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php index 0c4c78b582941..fb7bbd634d11f 100644 --- a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php +++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php @@ -7,7 +7,7 @@ namespace Magento\UrlRewriteGraphQl\Model\Resolver; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; @@ -45,7 +45,7 @@ public function resolve( array $args = null ): array { if (!isset($value['model'])) { - throw new GraphQlInputException(__('"model" value should be specified')); + throw new LocalizedException(__('"model" value should be specified')); } /** @var AbstractModel $entity */ From c498773af5dc671b511534d759645808c7ae04c3 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 15:28:46 +0200 Subject: [PATCH 800/812] GraphQL-39: Manage Shipping methods on Cart --- app/code/Magento/QuoteGraphQl/composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 881450745b84a..1bf4d581a5fe3 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -9,7 +9,8 @@ "magento/module-checkout": "*", "magento/module-catalog": "*", "magento/module-store": "*", - "magento/module-customer": "*" + "magento/module-customer": "*", + "magento/module-customer-graph-ql": "*" }, "suggest": { "magento/module-graph-ql": "*" From 645cdd2fe463d0b200a2e87848eb79da3c716f8d Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 15:41:04 +0200 Subject: [PATCH 801/812] GraphQL-189: Replace GraphQlInputException on LocalizedException -- fix static tests --- .../Model/ProductLinkTypeResolverComposite.php | 2 +- .../Model/Resolver/Product/EntityIdToId.php | 4 ++-- .../Resolver/Product/MediaGalleryEntries.php | 11 ++++++++++- .../Model/Resolver/Product/NewFromTo.php | 10 +++++++++- .../Model/Resolver/Product/Options.php | 11 ++++++++++- .../Model/Resolver/Product/Price.php | 11 ++++++++++- .../Model/Resolver/Product/ProductLinks.php | 15 ++++++++++++--- .../Model/Resolver/Product/TierPrices.php | 15 ++++++++++++--- .../Resolver/Product/DownloadableOptions.php | 15 ++++++++++++--- .../Model/Resolver/AttributeOptions.php | 8 +++++++- .../EavGraphQl/Model/Resolver/Query/Type.php | 2 +- 11 files changed, 86 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php index fbce18dfb67a5..c1bf5c0b7bb1c 100644 --- a/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php +++ b/app/code/Magento/CatalogGraphQl/Model/ProductLinkTypeResolverComposite.php @@ -11,7 +11,7 @@ use Magento\Framework\GraphQl\Query\Resolver\TypeResolverInterface; /** - * {@inheritdoc} + * @inheritdoc */ class ProductLinkTypeResolverComposite implements TypeResolverInterface { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php index 962256ceff442..b3e76ea78d183 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php @@ -16,9 +16,9 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * Fixed the id related data in the product data - * * {@inheritdoc} + * + * Fixed the id related data in the product data */ class EntityIdToId implements ResolverInterface { diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php index 785cd75585d5d..f9bb3071ff378 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php @@ -8,6 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Framework\GraphQl\Config\Element\Field; @@ -19,9 +20,17 @@ class MediaGalleryEntries implements ResolverInterface { /** + * {@inheritdoc} + * * Format product's media gallery entry data to conform to GraphQL schema * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return array */ public function resolve( Field $field, diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php index 88ae457c9986f..eb9f0d401e3a1 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php @@ -19,9 +19,17 @@ class NewFromTo implements ResolverInterface { /** + * {@inheritdoc} + * * Transfer data from legacy news_from_date and news_to_date to new names corespondent fields * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param \Magento\Framework\GraphQl\Query\Resolver\ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return null|array */ public function resolve( Field $field, diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php index cb53ebdab4810..bb386833b5b75 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php @@ -8,6 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Option; @@ -20,9 +21,17 @@ class Options implements ResolverInterface { /** + * {@inheritdoc} + * * Format product's option data to conform to GraphQL schema * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return null|array */ public function resolve( Field $field, diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php index 3bc9057f06b01..ca29b46aae9f7 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php @@ -8,6 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Pricing\Price\FinalPrice; @@ -47,9 +48,17 @@ public function __construct( } /** + * {@inheritdoc} + * * Format product's tier price data to conform to GraphQL schema * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return array */ public function resolve( Field $field, diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php index b2a612d6ae02d..4a0fcfaa413fa 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php @@ -8,6 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\ProductLink\Link; @@ -15,9 +16,9 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * Format the product links information to conform to GraphQL schema representation - * * {@inheritdoc} + * + * Format the product links information to conform to GraphQL schema representation */ class ProductLinks implements ResolverInterface { @@ -27,9 +28,17 @@ class ProductLinks implements ResolverInterface private $linkTypes = ['related', 'upsell', 'crosssell']; /** + * {@inheritdoc} + * * Format product links data to conform to GraphQL schema * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return null|array */ public function resolve( Field $field, diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php index cf1b621ad65b6..e4a1b2889d470 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php @@ -8,6 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\TierPrice; @@ -15,16 +16,24 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * Format a product's tier price information to conform to GraphQL schema representation - * * {@inheritdoc} + * + * Format a product's tier price information to conform to GraphQL schema representation */ class TierPrices implements ResolverInterface { /** + * {@inheritdoc} + * * Format product's tier price data to conform to GraphQL schema * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return null|array */ public function resolve( Field $field, diff --git a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php index 0842c96ef4b1a..4d0bdb4c61f3e 100644 --- a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php +++ b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php @@ -8,6 +8,7 @@ namespace Magento\DownloadableGraphQl\Model\Resolver\Product; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Model\Product; use Magento\Downloadable\Helper\Data as DownloadableHelper; @@ -20,9 +21,9 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * Format for downloadable product types - * * {@inheritdoc} + * + * Format for downloadable product types */ class DownloadableOptions implements ResolverInterface { @@ -65,9 +66,17 @@ public function __construct( } /** + * {@inheritdoc} + * * Add downloadable options to configurable types * - * {@inheritdoc} + * @param \Magento\Framework\GraphQl\Config\Element\Field $field + * @param ContextInterface $context + * @param ResolveInfo $info + * @param array|null $value + * @param array|null $args + * @throws \Exception + * @return null|array */ public function resolve( Field $field, diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php b/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php index b0def15f3a0d4..e4c27adc60247 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/AttributeOptions.php @@ -47,7 +47,7 @@ public function __construct( } /** - * @inheritDoc + * @inheritdoc */ public function resolve( Field $field, @@ -67,6 +67,8 @@ public function resolve( } /** + * Get entity type + * * @param array $value * @return int * @throws LocalizedException @@ -81,6 +83,8 @@ private function getEntityType(array $value): int } /** + * Get attribute code + * * @param array $value * @return string * @throws LocalizedException @@ -95,6 +99,8 @@ private function getAttributeCode(array $value): string } /** + * Get attribute options data + * * @param int $entityType * @param string $attributeCode * @return array diff --git a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php index 390279f2cfe2e..ef21a26f1f62e 100644 --- a/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php +++ b/app/code/Magento/EavGraphQl/Model/Resolver/Query/Type.php @@ -36,7 +36,7 @@ class Type /** * @param CustomAttributeTypeLocatorInterface $typeLocator * @param TypeProcessor $typeProcessor - * @param $customTypes + * @param array $customTypes */ public function __construct( CustomAttributeTypeLocatorInterface $typeLocator, From a54fed5ce35eb5d6c6d1c95b4b5b94dd37a111b1 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 16:15:33 +0200 Subject: [PATCH 802/812] GraphQL-189: Replace GraphQlInputException on LocalizedException -- fix static tests --- .../CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php | 2 +- .../Model/Resolver/Product/MediaGalleryEntries.php | 4 +++- .../CatalogGraphQl/Model/Resolver/Product/NewFromTo.php | 4 +++- .../Magento/CatalogGraphQl/Model/Resolver/Product/Options.php | 2 +- .../Magento/CatalogGraphQl/Model/Resolver/Product/Price.php | 2 +- .../CatalogGraphQl/Model/Resolver/Product/ProductLinks.php | 2 +- .../CatalogGraphQl/Model/Resolver/Product/TierPrices.php | 4 ++-- .../Model/Resolver/Product/DownloadableOptions.php | 4 ++-- 8 files changed, 14 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php index b3e76ea78d183..ada3caad5f9f8 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/EntityIdToId.php @@ -16,7 +16,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * {@inheritdoc} + * @inheritdoc * * Fixed the id related data in the product data */ diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php index f9bb3071ff378..c8f167da583d3 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/MediaGalleryEntries.php @@ -15,12 +15,14 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** + * @inheritdoc + * * Format a product's media gallery information to conform to GraphQL schema representation */ class MediaGalleryEntries implements ResolverInterface { /** - * {@inheritdoc} + * @inheritdoc * * Format product's media gallery entry data to conform to GraphQL schema * diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php index eb9f0d401e3a1..12016282a3081 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/NewFromTo.php @@ -14,12 +14,14 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** + * @inheritdoc + * * Format the new from and to typo of legacy fields news_from_date and news_to_date */ class NewFromTo implements ResolverInterface { /** - * {@inheritdoc} + * @inheritdoc * * Transfer data from legacy news_from_date and news_to_date to new names corespondent fields * diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php index bb386833b5b75..76602288039c5 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Options.php @@ -21,7 +21,7 @@ class Options implements ResolverInterface { /** - * {@inheritdoc} + * @inheritdoc * * Format product's option data to conform to GraphQL schema * diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php index ca29b46aae9f7..55d930101fb60 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price.php @@ -48,7 +48,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * * Format product's tier price data to conform to GraphQL schema * diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php index 4a0fcfaa413fa..f72f873fc8e55 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php @@ -28,7 +28,7 @@ class ProductLinks implements ResolverInterface private $linkTypes = ['related', 'upsell', 'crosssell']; /** - * {@inheritdoc} + * @inheritdoc * * Format product links data to conform to GraphQL schema * diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php index e4a1b2889d470..726ef91c56880 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/TierPrices.php @@ -16,14 +16,14 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * {@inheritdoc} + * @inheritdoc * * Format a product's tier price information to conform to GraphQL schema representation */ class TierPrices implements ResolverInterface { /** - * {@inheritdoc} + * @inheritdoc * * Format product's tier price data to conform to GraphQL schema * diff --git a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php index 4d0bdb4c61f3e..a1e25663a9c3d 100644 --- a/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php +++ b/app/code/Magento/DownloadableGraphQl/Model/Resolver/Product/DownloadableOptions.php @@ -21,7 +21,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * {@inheritdoc} + * @inheritdoc * * Format for downloadable product types */ @@ -66,7 +66,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc * * Add downloadable options to configurable types * From 39225d4aceee4f6f6cf2d8da09235333c8b8961d Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 16:21:09 +0200 Subject: [PATCH 803/812] GraphQL-39: Manage Shipping methods on Cart -- fixes after merge --- app/code/Magento/QuoteGraphQl/etc/schema.graphqls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 3e622f9fa5412..edc643973ce77 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -6,7 +6,7 @@ type Query { } type Mutation { - createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates an empty shopping cart for a guest or logged in user") + createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates an empty shopping cart for a guest or logged in user") applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\ApplyCouponToCart") removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Coupon\\RemoveCouponFromCart") setShippingAddressesOnCart(input: SetShippingAddressesOnCartInput): SetShippingAddressesOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingAddressesOnCart") From 7f41544848b0496779a4a8d07ccb8869d9ef435b Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 16:23:51 +0200 Subject: [PATCH 804/812] GraphQL-189: Replace GraphQlInputException on LocalizedException -- fix static tests --- .../CatalogGraphQl/Model/Resolver/Product/ProductLinks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php index f72f873fc8e55..4d1b11a74b9d4 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductLinks.php @@ -16,7 +16,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; /** - * {@inheritdoc} + * @inheritdoc * * Format the product links information to conform to GraphQL schema representation */ From 6d26686321561fb0460f8024d89af2483a2dfda9 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 19 Nov 2018 17:35:28 +0200 Subject: [PATCH 805/812] MAGETWO-94424: Wrong product and shipping prices are applying on admin orders --- app/code/Magento/Store/Model/Store.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Store/Model/Store.php b/app/code/Magento/Store/Model/Store.php index 32c9a78448428..c92d62cd0bbe3 100644 --- a/app/code/Magento/Store/Model/Store.php +++ b/app/code/Magento/Store/Model/Store.php @@ -412,7 +412,7 @@ public function __construct( } /** - * @return string[] + * @inheritdoc */ public function __sleep() { @@ -786,7 +786,7 @@ public function isFrontUrlSecure() } /** - * @return bool + * @inheritdoc */ public function isUrlSecure() { @@ -1338,6 +1338,8 @@ public function getIdentities() } /** + * Get store path + * * @return string */ public function getStorePath() @@ -1347,8 +1349,7 @@ public function getStorePath() } /** - * {@inheritdoc} - * @since 100.1.0 + * @inheritdoc */ public function getScopeType() { @@ -1356,8 +1357,7 @@ public function getScopeType() } /** - * {@inheritdoc} - * @since 100.1.0 + * @inheritdoc */ public function getScopeTypeName() { @@ -1365,7 +1365,7 @@ public function getScopeTypeName() } /** - * {@inheritdoc} + * @inheritdoc */ public function getExtensionAttributes() { @@ -1373,8 +1373,7 @@ public function getExtensionAttributes() } /** - * @param \Magento\Store\Api\Data\StoreExtensionInterface $extensionAttributes - * @return $this + * @inheritdoc */ public function setExtensionAttributes( \Magento\Store\Api\Data\StoreExtensionInterface $extensionAttributes From faa85353df4be28674a07d406ff87e422284b985 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 18:48:55 +0200 Subject: [PATCH 806/812] GraphQL-202: Products: Email to a Friend --- .../Model/Resolver/SendEmailToFriend.php | 179 +++++++++++------- .../Model/Validation/Validation.php | 69 ------- .../Magento/SendFriendGraphQl/composer.json | 26 +++ .../SendFriendGraphQl/etc/schema.graphqls | 9 +- composer.json | 1 + composer.lock | 2 +- 6 files changed, 145 insertions(+), 141 deletions(-) delete mode 100644 app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php create mode 100644 app/code/Magento/SendFriendGraphQl/composer.json diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php index 56f6d20b20f18..06c5da94819df 100644 --- a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -7,38 +7,60 @@ namespace Magento\SendFriendGraphQl\Model\Resolver; +use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\DataObjectFactory; +use Magento\Framework\Event\ManagerInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\SendFriend\Model\SendFriend; +use Magento\SendFriend\Model\SendFriendFactory; +/** + * @inheritdoc + */ class SendEmailToFriend implements ResolverInterface { /** - * @var SendFriend + * @var SendFriendFactory */ - private $sendFriend; + private $sendFriendFactory; + /** * @var ProductRepositoryInterface */ private $productRepository; + /** * @var DataObjectFactory */ private $dataObjectFactory; + /** + * @var ManagerInterface + */ + private $eventManager; + + /** + * @param SendFriendFactory $sendFriendFactory + * @param ProductRepositoryInterface $productRepository + * @param DataObjectFactory $dataObjectFactory + * @param ManagerInterface $eventManager + */ public function __construct( - SendFriend $sendFriend, + SendFriendFactory $sendFriendFactory, ProductRepositoryInterface $productRepository, - DataObjectFactory $dataObjectFactory + DataObjectFactory $dataObjectFactory, + ManagerInterface $eventManager ) { - $this->sendFriend = $sendFriend; + $this->sendFriendFactory = $sendFriendFactory; $this->productRepository = $productRepository; $this->dataObjectFactory = $dataObjectFactory; + $this->eventManager = $eventManager; } /** @@ -46,102 +68,131 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - if ($this->sendFriend->getMaxSendsToFriend() && $this->sendFriend->isExceedLimit()) { + /** @var SendFriend $sendFriend */ + $sendFriend = $this->sendFriendFactory->create(); + + if ($sendFriend->getMaxSendsToFriend() && $sendFriend->isExceedLimit()) { throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', - $this->sendFriend->getMaxSendsToFriend() + $sendFriend->getMaxSendsToFriend() )); } - $product = $this->getProductFromRepository($args['input']['params']['product_id']); - $senderArray = $this->getSenderArrayFromArgs($args); - $recipientsArray = $this->getRecipientsArray($args); - //@todo clarify if event should be dispatched - //$this->_eventManager->dispatch('sendfriend_product', ['product' => $product]); - $this->sendFriend->setSender($senderArray); - $this->sendFriend->setRecipients($recipientsArray); - $this->sendFriend->setProduct($product); - - $this->prepareDataForValidation($args, $recipientsArray); - $validationResult = $this->sendFriend->validate(); - $this->addRecipientNameValidation($args); - if ($validationResult !== true) { - throw new GraphQlInputException(__(implode($validationResult))); - } + $product = $this->getProduct($args['input']['product_id']); + $this->eventManager->dispatch('sendfriend_product', ['product' => $product]); + $sendFriend->setProduct($product); - $this->sendFriend->send(); + $senderData = $this->extractSenderData($args); + $sendFriend->setSender($senderData); - return array_merge($senderArray, $recipientsArray); - } + $recipientsData = $this->extractRecipientsData($args); + $sendFriend->setRecipients($recipientsData); - private function prepareDataForValidation(array $args, array $recipientsArray): void - { - $sender = $this->dataObjectFactory->create()->setData([ - 'name' => $args['input']['sender']['name'], - 'email'=> $args['input']['sender']['email'], - 'message' => $args['input']['sender']['message'], - ]); - $emails = []; - foreach ($recipientsArray['recipients'] as $recipient) { - $emails[] = $recipient['email']; - } - $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + $this->validateSendFriendModel($sendFriend, $senderData, $recipientsData); + $sendFriend->send(); - $this->sendFriend->setData('_sender', $sender); - $this->sendFriend->setData('_recipients', $recipients); + return array_merge($senderData, $recipientsData); } /** - * @param array $args + * Validate send friend model + * + * @param SendFriend $sendFriend + * @param array $senderData + * @param array $recipientsData + * @return void * @throws GraphQlInputException */ - private function addRecipientNameValidation(array $args): void + private function validateSendFriendModel(SendFriend $sendFriend, array $senderData, array $recipientsData): void { - foreach ($args['input']['recipients'] as $recipient) { - if (empty($recipient['name'])) { - throw new GraphQlInputException( - __('Please Provide Name for Recipient with this Email Address: ' . $recipient['email'] - )); - } + $sender = $this->dataObjectFactory->create()->setData($senderData['sender']); + $sendFriend->setData('_sender', $sender); + + $emails = array_column($recipientsData['recipients'], 'email'); + $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + $sendFriend->setData('_recipients', $recipients); + + $validationResult = $sendFriend->validate(); + if ($validationResult !== true) { + throw new GraphQlInputException(__(implode($validationResult))); } } /** + * Get product + * * @param int $productId - * @return bool|\Magento\Catalog\Api\Data\ProductInterface + * @return ProductInterface + * @throws GraphQlNoSuchEntityException */ - private function getProductFromRepository(int $productId) + private function getProduct(int $productId): ProductInterface { try { $product = $this->productRepository->getById($productId); if (!$product->isVisibleInCatalog()) { - return false; + throw new GraphQlNoSuchEntityException( + __("The product that was requested doesn't exist. Verify the product and try again.") + ); } - } catch (NoSuchEntityException $noEntityException) { - return false; + } catch (NoSuchEntityException $e) { + throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); } - return $product; } - private function getRecipientsArray(array $args): array + /** + * Extract recipients data + * + * @param array $args + * @return array + * @throws GraphQlInputException + */ + private function extractRecipientsData(array $args): array { - $recipientsArray = []; + $recipients = []; foreach ($args['input']['recipients'] as $recipient) { - $recipientsArray[] = [ + if (empty($recipient['name'])) { + throw new GraphQlInputException(__('Please provide Name for all of recipients.')); + } + + if (empty($recipient['email'])) { + throw new GraphQlInputException(__('Please provide Email for all of recipients.')); + } + + $recipients[] = [ 'name' => $recipient['name'], 'email' => $recipient['email'], ]; } - return ['recipients' => $recipientsArray]; + return ['recipients' => $recipients]; } - private function getSenderArrayFromArgs(array $args): array + /** + * Extract sender data + * + * @param array $args + * @return array + * @throws GraphQlInputException + */ + private function extractSenderData(array $args): array { - return ['sender' => [ - 'name' => $args['input']['sender']['name'], - 'email' => $args['input']['sender']['email'], - 'message' => $args['input']['sender']['message'], - ] - ]; + if (empty($args['input']['sender']['name'])) { + throw new GraphQlInputException(__('Please provide Name of sender.')); + } + + if (empty($args['input']['sender']['email'])) { + throw new GraphQlInputException(__('Please provide Email of sender.')); + } + + if (empty($args['input']['sender']['message'])) { + throw new GraphQlInputException(__('Please provide Message.')); + } + + return [ + 'sender' => [ + 'name' => $args['input']['sender']['name'], + 'email' => $args['input']['sender']['email'], + 'message' => $args['input']['sender']['message'], + ], + ]; } } diff --git a/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php b/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php deleted file mode 100644 index 49f7feeaba489..0000000000000 --- a/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\SendFriendGraphQl\Model\Validation; - -use Magento\Framework\DataObjectFactory; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\SendFriend\Model\SendFriend; - -class Validation -{ - /** - * @var SendFriend - */ - private $sendFriend; - /** - * @var DataObjectFactory - */ - private $dataObjectFactory; - - public function __construct( - DataObjectFactory $dataObjectFactory, - SendFriend $sendFriend - ) { - $this->sendFriend = $sendFriend; - $this->dataObjectFactory = $dataObjectFactory; - } - - /** - * @param $args - * @param array $recipientsArray - * @throws GraphQlInputException - */ - public function validate($args, array $recipientsArray): void - { - $this->prepareDataForSendFriendValidation($args, $recipientsArray); - $validationResult = $this->sendFriend->validate(); - if ($validationResult !== true) { - throw new GraphQlInputException(__(implode($validationResult))); - } - if ($this->sendFriend->getMaxSendsToFriend() && $this->sendFriend->isExceedLimit()) { - throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', - $this->sendFriend->getMaxSendsToFriend() - )); - } - } - - private function prepareDataForSendFriendValidation(array $args, array $recipientsArray): void - { - $sender = $this->dataObjectFactory->create()->setData([ - 'name' => $args['input']['sender']['name'], - 'email'=> $args['input']['sender']['email'], - 'message' => $args['input']['sender']['message'], - ]); - $emails = []; - foreach ($recipientsArray['recipients'] as $recipient) { - $emails[] = $recipient['email']; - } - $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); - - $this->sendFriend->setData('_sender', $sender); - $this->sendFriend->setData('_recipients', $recipients); - } - -} \ No newline at end of file diff --git a/app/code/Magento/SendFriendGraphQl/composer.json b/app/code/Magento/SendFriendGraphQl/composer.json new file mode 100644 index 0000000000000..10d7e63bfc770 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/composer.json @@ -0,0 +1,26 @@ +{ + "name": "magento/module-send-friend-graph-ql", + "description": "N/A", + "type": "magento2-module", + "require": { + "php": "~7.1.3||~7.2.0", + "magento/framework": "*", + "magento/module-catalog": "*", + "magento/module-send-friend": "*" + }, + "suggest": { + "magento/module-graph-ql": "*" + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\SendFriendGraphGl\\": "" + } + } +} diff --git a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls index 4123387650838..3915d48681ab1 100644 --- a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls @@ -6,9 +6,9 @@ type Mutation { } input SendEmailToFriendSenderInput { + product_id: Int! sender: Sender! - params: Params! - recipients: [Recipient] + recipients: [Recipient!]! } type Sender { @@ -16,17 +16,12 @@ type Sender { email: String! message: String! } -type Params { - product_id: Int! - category_id: Int! -} type Recipient { name: String! email: String! } - type SendEmailToFriendOutput { sender: Sender recipients: [Recipient] diff --git a/composer.json b/composer.json index 3f8f0a033c893..99f5beeb9c7e7 100644 --- a/composer.json +++ b/composer.json @@ -208,6 +208,7 @@ "magento/module-search": "*", "magento/module-security": "*", "magento/module-send-friend": "*", + "magento/module-send-friend-graph-ql": "*", "magento/module-shipping": "*", "magento/module-signifyd": "*", "magento/module-sitemap": "*", diff --git a/composer.lock b/composer.lock index 1d101c8aaaf15..a3e7a72e69026 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d6640ddfd342feceaec44c406c056f57", + "content-hash": "886f5497f18a46a42d05cc672f1b8f2f", "packages": [ { "name": "braintree/braintree_php", From b6e07229fbd610a6617d47ab4c73cae0c335bb8f Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 18:53:31 +0200 Subject: [PATCH 807/812] GraphQL-202: Products: Email to a Friend --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 36b4dca023191..f26b71f1cc392 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7538e15ea4ff1378cf55983ce9acba82", + "content-hash": "93418bd14ad2d9f54f4059550ded7061", "packages": [ { "name": "braintree/braintree_php", From a653c2baf540fa0a7c42f84a8d72e9228aaeb9d4 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 20:18:31 +0200 Subject: [PATCH 808/812] GraphQL-202: Products: Email to a Friend --- app/code/Magento/SendFriendGraphQl/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app/code/Magento/SendFriendGraphQl/README.md diff --git a/app/code/Magento/SendFriendGraphQl/README.md b/app/code/Magento/SendFriendGraphQl/README.md new file mode 100644 index 0000000000000..d8051922ddad7 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/README.md @@ -0,0 +1,3 @@ +# SendFriendGraphQl + +**SendFriendGraphQl** provides support of GraphQL for SendFriend functionality. From 0bdc2fd3918e9fbd6ab48dc5cd97b270b17d163a Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 20:35:53 +0200 Subject: [PATCH 809/812] GraphQL-202: Products: Email to a Friend -- fix static tests --- .../SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php | 3 ++- app/code/Magento/SendFriendGraphQl/registration.php | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php index 06c5da94819df..2b183ca209c0c 100644 --- a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -72,7 +72,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $sendFriend = $this->sendFriendFactory->create(); if ($sendFriend->getMaxSendsToFriend() && $sendFriend->isExceedLimit()) { - throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', + throw new GraphQlInputException( + __('You can\'t send messages more than %1 times an hour.', $sendFriend->getMaxSendsToFriend() )); } diff --git a/app/code/Magento/SendFriendGraphQl/registration.php b/app/code/Magento/SendFriendGraphQl/registration.php index c41607a0dc864..5988738268147 100644 --- a/app/code/Magento/SendFriendGraphQl/registration.php +++ b/app/code/Magento/SendFriendGraphQl/registration.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); use Magento\Framework\Component\ComponentRegistrar; From b6d9adeed9bd275e0e819c33af35dff134b17834 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 20:40:10 +0200 Subject: [PATCH 810/812] GraphQL-202: Products: Email to a Friend -- fix static tests --- app/code/Magento/SendFriendGraphQl/composer.json | 2 +- app/code/Magento/SendFriendGraphQl/etc/module.xml | 2 +- app/code/Magento/SendFriendGraphQl/registration.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/SendFriendGraphQl/composer.json b/app/code/Magento/SendFriendGraphQl/composer.json index 10d7e63bfc770..d401f57b2257a 100644 --- a/app/code/Magento/SendFriendGraphQl/composer.json +++ b/app/code/Magento/SendFriendGraphQl/composer.json @@ -20,7 +20,7 @@ "registration.php" ], "psr-4": { - "Magento\\SendFriendGraphGl\\": "" + "Magento\\SendFriendGraphQl\\": "" } } } diff --git a/app/code/Magento/SendFriendGraphQl/etc/module.xml b/app/code/Magento/SendFriendGraphQl/etc/module.xml index 14d792198cd5f..3df33266cac6e 100644 --- a/app/code/Magento/SendFriendGraphQl/etc/module.xml +++ b/app/code/Magento/SendFriendGraphQl/etc/module.xml @@ -7,5 +7,5 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_SendFriendGraphGl"/> + <module name="Magento_SendFriendGraphQl"/> </config> diff --git a/app/code/Magento/SendFriendGraphQl/registration.php b/app/code/Magento/SendFriendGraphQl/registration.php index 5988738268147..13ec47b16abdb 100644 --- a/app/code/Magento/SendFriendGraphQl/registration.php +++ b/app/code/Magento/SendFriendGraphQl/registration.php @@ -7,4 +7,4 @@ use Magento\Framework\Component\ComponentRegistrar; -ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_SendFriendGraphGl', __DIR__); +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_SendFriendGraphQl', __DIR__); From 05c1c8a02790974b5574f66a3ba81f721c325785 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 19 Nov 2018 21:00:42 +0200 Subject: [PATCH 811/812] GraphQL-202: Products: Email to a Friend -- fix static tests --- .../SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php index 2b183ca209c0c..c0c01c71df764 100644 --- a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -73,9 +73,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value if ($sendFriend->getMaxSendsToFriend() && $sendFriend->isExceedLimit()) { throw new GraphQlInputException( - __('You can\'t send messages more than %1 times an hour.', - $sendFriend->getMaxSendsToFriend() - )); + __('You can\'t send messages more than %1 times an hour.', $sendFriend->getMaxSendsToFriend()) + ); } $product = $this->getProduct($args['input']['product_id']); From 3694c65e95fa12258afdfc561ff29ad23fb00969 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Tue, 20 Nov 2018 12:12:37 +0100 Subject: [PATCH 812/812] Added model to category data upon the hydration --- app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php index e783c749fdc6e..d2c1fc8f7be9f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php +++ b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php @@ -56,6 +56,7 @@ public function hydrateCategory(Category $category, $basicFieldsOnly = false) : $categoryData['id'] = $category->getId(); $categoryData['children'] = []; $categoryData['available_sort_by'] = $category->getAvailableSortBy(); + $categoryData['model'] = $category; return $this->flattener->flatten($categoryData); } }